00001
00002
00003
00004
00005 #include <stdio.h>
00006 #include <string.h>
00007 #include <stdarg.h>
00008 #include <stdlib.h>
00009 #include <ctype.h>
00010 #ifdef _WIN32
00011 # include <io.h>
00012 #else
00013 # include <unistd.h>
00014 #endif
00015 #include "getargs.h"
00016 #include "hash.h"
00017 #include "cgnslib.h"
00018 #include "cgns_header.h"
00019 #include "cgnames.h"
00020
00021 #if !defined(CGNS_VERSION) || CGNS_VERSION < 2300
00022 # error You need at least CGNS Version 2.3
00023 #endif
00024
00025 #ifndef CG_MODE_READ
00026 # define CG_MODE_READ MODE_READ
00027 # define CG_MODE_MODIFY MODE_MODIFY
00028 #endif
00029
00030 #if CGNS_VERSION < 2420
00031 # define cg_free free
00032 #endif
00033
00034 #if CGNS_VERSION >= 3000
00035 # define USE_MID_NODES
00036 #endif
00037
00038 static int FileVersion;
00039 static int LibraryVersion = CGNS_VERSION;
00040
00041 static int verbose = 0;
00042 static int nwarn = 0, nerr = 0, totwarn = 0;
00043 static int dowarn = 3, doerr = 1;
00044 static int cgnsfn, cgnsbase, cgnszone;
00045
00046 static int CellDim, PhyDim;
00047 static int BaseClass;
00048 static int *pBaseUnits, BaseUnits[9];
00049
00050 static int BaseIter;
00051 static int NumSteps;
00052
00053 typedef struct {
00054 float x, y, z;
00055 } VERTEX;
00056
00057 typedef struct {
00058 int e1, f1;
00059 int e2, f2;
00060 int nnodes;
00061 int *nodes;
00062 } FACE;
00063
00064 typedef struct {
00065 char name[33];
00066 ElementType_t type;
00067 int is, ie, ib;
00068 int nv, ns, ne, nn;
00069 int *elements;
00070 int *parent;
00071 int rind[2];
00072 int invalid;
00073 } ELEMSET;
00074
00075 typedef struct {
00076 char name[33];
00077 ZoneType_t type;
00078 int idim;
00079 int dims[3][3];
00080 int nnodes;
00081 int maxnode;
00082 int dataclass;
00083 int *punits, units[9];
00084 int nsets;
00085 int nv, ns, ne, nn;
00086 ELEMSET *sets;
00087 HASH *faces;
00088 int nextnodes;
00089 int *extnodes;
00090 } ZONE;
00091
00092 static int MaxZones = 0;
00093 static int NumZones = 0;
00094 static ZONE *Zones;
00095
00096 typedef char CGNSNAME[33];
00097
00098 static int MaxFamily = 0;
00099 static int NumFamily = 0;
00100 static CGNSNAME *Family;
00101
00102 static int MaxFlowSolution = 0;
00103 static int NumFlowSolution = 0;
00104 static CGNSNAME *FlowSolution;
00105
00106 static int MaxGridCoordinate = 0;
00107 static int NumGridCoordinate = 0;
00108 static CGNSNAME *GridCoordinate;
00109
00110 static int MaxArbitraryGrid = 0;
00111 static int NumArbitraryGrid = 0;
00112 static CGNSNAME *ArbitraryGrid;
00113
00114 static int MaxRigidGrid = 0;
00115 static int NumRigidGrid = 0;
00116 static CGNSNAME *RigidGrid;
00117
00118
00119
00120 static char options[] = "vVuUw:e";
00121
00122 static char *usgmsg[] = {
00123 "usage : cgnscheck [options] CGNSfile [CGNSoutfile]",
00124 "options:",
00125 " -v : verbose output",
00126 " -V : more verbose - print descriptors",
00127 " -u : update CGNS file to CGNS Library Version and check",
00128 " -U : update CGNS file to CGNS Library Version only",
00129 " -w<level> : warning level output (0 to 3)",
00130 " -e : don't print error",
00131 NULL
00132 };
00133
00134
00135
00136 static void warning (int level, char *format, ...)
00137 {
00138 va_list arg;
00139 if (level <= dowarn) {
00140 va_start (arg, format);
00141 printf ("WARNING:");
00142 vprintf (format, arg);
00143 va_end(arg);
00144 putchar ('\n');
00145 nwarn++;
00146 }
00147 totwarn++;
00148 }
00149
00150 static void error (char *format, ...)
00151 {
00152 va_list arg;
00153 if (doerr) {
00154 va_start (arg, format);
00155 printf ("ERROR:");
00156 vprintf (format, arg);
00157 va_end(arg);
00158 putchar ('\n');
00159 }
00160 nerr++;
00161 }
00162
00163 static void error_exit(char *func)
00164 {
00165 printf("CGNSlib ERROR:");
00166 if (func != NULL && *func)
00167 printf("%s:", func);
00168 printf("%s\n", cg_get_error());
00169 exit(1);
00170 }
00171
00172
00173
00174 static void create_names (int cnt, int *maxcnt, CGNSNAME **namelist)
00175 {
00176 CGNSNAME *names = *namelist;
00177
00178 if (cnt > *maxcnt) {
00179 if (*maxcnt)
00180 names = (CGNSNAME *) realloc (names, cnt * sizeof(CGNSNAME));
00181 else
00182 names = (CGNSNAME *) malloc (cnt * sizeof(CGNSNAME));
00183 if (names == NULL) {
00184 fprintf (stderr, "malloc failed for cgns name list\n");
00185 exit (1);
00186 }
00187 *maxcnt = cnt;
00188 *namelist = names;
00189 }
00190 }
00191
00192
00193
00194 #ifdef CG_MAX_GOTO_DEPTH
00195 # define MAX_GOTO_DEPTH CG_MAX_GOTO_DEPTH
00196 #else
00197 # define MAX_GOTO_DEPTH 20
00198 #endif
00199
00200 static char goLabel[MAX_GOTO_DEPTH][33];
00201 static int goIndex[MAX_GOTO_DEPTH];
00202 static int goDepth = 0;
00203
00204
00205
00206 static void goto_node ()
00207 {
00208 int n, ier;
00209 char *labels[MAX_GOTO_DEPTH];
00210
00211 #if CGNS_VERSION >= 2500
00212 for (n = 0; n < goDepth; n++)
00213 labels[n] = goLabel[n];
00214 # if CGNS_VERSION > 2500
00215 ier = cg_golist (cgnsfn, cgnsbase, goDepth, labels, goIndex);
00216 if (ier) error_exit ("cg_golist");
00217 # else
00218 ier = cgi_get_posit(cgnsfn, cgnsbase, goDepth, goIndex, labels);
00219 if (ier) error_exit("cgi_get_posit");
00220 # endif
00221 #else
00222 posit_base = cgnsbase;
00223 posit_zone = 0;
00224 for (n = 0; n < goDepth; n++) {
00225 labels[n] = goLabel[n];
00226 if (strcmp (goLabel[n], "Zone_t") == 0)
00227 posit_zone = goIndex[n];
00228 }
00229
00230 if (goDepth == 0)
00231 strcpy (posit_label, "CGNSBase_t");
00232 else
00233 strcpy (posit_label, goLabel[goDepth-1]);
00234
00235 posit = cgi_get_posit (cgnsfn, cgnsbase, goDepth, goIndex, labels, &ier);
00236 if (ier) error_exit("cgi_get_posit");
00237 #endif
00238 }
00239
00240
00241
00242 static void go_absolute (char *dsname, ...)
00243 {
00244 int num;
00245 char *name = dsname;
00246 va_list arg;
00247
00248 va_start (arg, dsname);
00249 goDepth = 0;
00250 while (name != NULL) {
00251 num = va_arg (arg, int);
00252 if (goDepth == MAX_GOTO_DEPTH) {
00253 fprintf (stderr, "maximum depth of goto exceeded\n");
00254 exit (1);
00255 }
00256 strncpy (goLabel[goDepth], name, 32);
00257 goLabel[goDepth][32] = 0;
00258 goIndex[goDepth] = num;
00259 goDepth++;
00260 name = va_arg (arg, char *);
00261 }
00262 va_end (arg);
00263 goto_node();
00264 }
00265
00266
00267
00268 static void go_relative (char *dsname, ...)
00269 {
00270 int num;
00271 char *name = dsname;
00272 va_list arg;
00273
00274 va_start (arg, dsname);
00275 while (name != NULL) {
00276 num = va_arg (arg, int);
00277 if (num < 1) break;
00278 if (0 == strcmp (name, "..")) {
00279 goDepth -= num;
00280 if (goDepth < 0) goDepth = 0;
00281 }
00282 else if (strcmp (name, ".")) {
00283 if (goDepth == MAX_GOTO_DEPTH) {
00284 fprintf (stderr, "maximum depth of goto exceeded\n");
00285 exit (1);
00286 }
00287 strncpy (goLabel[goDepth], name, 32);
00288 goLabel[goDepth][32] = 0;
00289 goIndex[goDepth++] = num;
00290 }
00291 name = va_arg (arg, char *);
00292 }
00293 va_end (arg);
00294 goto_node();
00295 }
00296
00297
00298
00299 static int check_node (char *label) {
00300 int nchild;
00301 double pid, *ids;
00302
00303 if (cgi_posit_id (&pid)) return CG_ERROR;
00304 if (cgi_get_nodes (pid, label, &nchild, &ids)) return CG_ERROR;
00305 if (nchild) {
00306 cg_free (ids);
00307 return CG_OK;
00308 }
00309 return CG_NODE_NOT_FOUND;
00310 }
00311
00312
00313
00314 static int read_gridlocation (GridLocation_t *location)
00315 {
00316 int ierr = check_node ("GridLocation_t");
00317 if (ierr == CG_OK)
00318 return cg_gridlocation_read (location);
00319 return ierr;
00320 }
00321
00322
00323
00324 static int read_ordinal (int *ordinal)
00325 {
00326 int ierr = check_node ("Ordinal_t");
00327 if (ierr == CG_OK)
00328 return cg_ordinal_read (ordinal);
00329 return ierr;
00330 }
00331
00332
00333
00334 static int read_rind (int *rind)
00335 {
00336 int ierr = check_node ("Rind_t");
00337 if (ierr == CG_OK)
00338 return cg_rind_read (rind);
00339 return ierr;
00340 }
00341
00342
00343
00344 static int check_interpolants (void)
00345 {
00346 int n, na, ndim, dims[12];
00347 DataType_t dtype;
00348 char name[33];
00349
00350 if (cg_narrays (&na)) error_exit ("cg_narrays");
00351 for (n = 1; n <= na; n++) {
00352 if (cg_array_info (n, name, &dtype, &ndim, dims))
00353 error_exit ("cg_array_info");
00354 if (0 == strcmp (name, "InterpolantsDonor")) return 1;
00355 }
00356 return 0;
00357 }
00358
00359
00360
00361 static char *temporary_file (char *basename)
00362 {
00363 char *p, *temp;
00364 int n;
00365
00366 if (basename == NULL || !*basename)
00367 basename = "cgnstmpfile";
00368 n = strlen (basename);
00369 temp = (char *) malloc (n + 10);
00370 if (temp == NULL) {
00371 fprintf (stderr, "malloc failed for temp filename\n");
00372 exit (1);
00373 }
00374 sprintf (temp, "%s.tmp", basename);
00375 p = temp + strlen(temp);
00376 for (n = 0; n < 1000; n++) {
00377 sprintf (p, "%3.3d~", n);
00378 if (access (temp, 0)) return temp;
00379 }
00380 fprintf (stderr, "failed to create temporary filename\n");
00381 exit (1);
00382 }
00383
00384
00385
00386 static void copy_file (char *oldfile, char *newfile)
00387 {
00388 int c;
00389 FILE *oldfp, *newfp;
00390
00391 if (NULL == (oldfp = fopen (oldfile, "rb"))) {
00392 fprintf (stderr, "error opening input file for reading\n");
00393 exit (1);
00394 }
00395 if (NULL == (newfp = fopen (newfile, "w+b"))) {
00396 fclose (oldfp);
00397 fprintf (stderr, "error opening output file for writing\n");
00398 exit (1);
00399 }
00400 while (EOF != (c = getc (oldfp)))
00401 putc (c, newfp);
00402 fclose (oldfp);
00403 fclose (newfp);
00404 }
00405
00406
00407
00408 static char *update_version (char *cgnsfile, char *outfile)
00409 {
00410 char *tempfile;
00411 float file_version;
00412
00413 if (verbose) {
00414 puts ("checking file version");
00415 fflush (stdout);
00416 }
00417 if (cg_open (cgnsfile, CG_MODE_READ, &cgnsfn) ||
00418 cg_version (cgnsfn, &file_version) ||
00419 cg_close (cgnsfn))
00420 cg_error_exit ();
00421 if (LibraryVersion <= (int)(file_version * 1000.0 + 0.5)) {
00422 puts ("file version is current");
00423 return cgnsfile;
00424 }
00425 if (verbose) {
00426 printf ("creating a working copy of %s\n", cgnsfile);
00427 fflush (stdout);
00428 }
00429 tempfile = temporary_file (cgnsfile);
00430 copy_file (cgnsfile, tempfile);
00431 if (verbose) {
00432 printf ("updating version number for %s\n", tempfile);
00433 fflush (stdout);
00434 }
00435 if (cg_open (tempfile, CG_MODE_MODIFY, &cgnsfn) || cg_close (cgnsfn)) {
00436 unlink (tempfile);
00437 cg_error_exit ();
00438 }
00439 if (NULL == outfile || !*outfile) outfile = cgnsfile;
00440 if (verbose) {
00441 printf ("renaming %s -> %s\n", tempfile, outfile);
00442 fflush (stdout);
00443 }
00444 unlink (outfile);
00445 if (rename (tempfile, outfile)) {
00446 fprintf (stderr, "rename %s -> %s failed\n", tempfile, outfile);
00447 exit (1);
00448 }
00449 free (tempfile);
00450 return outfile;
00451 }
00452
00453
00454
00455 static int sort_nodes (const void *n1, const void *n2)
00456 {
00457 return (*((int *)n1) - *((int *)n2));
00458 }
00459
00460
00461
00462 static int compare_faces (void *v1, void *v2)
00463 {
00464 int i;
00465 FACE *f1 = (FACE *)v1;
00466 FACE *f2 = (FACE *)v2;
00467
00468 if (f1->nnodes != f2->nnodes)
00469 return (f1->nnodes - f2->nnodes);
00470 for (i = 0; i < f1->nnodes; i++) {
00471 if (f1->nodes[i] != f2->nodes[i])
00472 return (f1->nodes[i] - f2->nodes[i]);
00473 }
00474 return (0);
00475 }
00476
00477
00478
00479 static unsigned hash_face (void *v)
00480 {
00481 FACE *f = (FACE *)v;
00482 int n;
00483 unsigned hash = 0;
00484
00485 for (n = 0; n < f->nnodes; n++)
00486 hash += (unsigned)f->nodes[n];
00487 return (hash);
00488 }
00489
00490
00491
00492 static int find_extnode (ZONE *z, int node)
00493 {
00494 int lo = 0, hi = z->nextnodes - 1, mid;
00495
00496 if (node == z->extnodes[lo]) return node;
00497 if (node == z->extnodes[hi]) return node;
00498 while (lo <= hi) {
00499 mid = (lo + hi) >> 1;
00500 if (node == z->extnodes[mid]) return node;
00501 if (node < z->extnodes[mid])
00502 hi = mid - 1;
00503 else
00504 lo = mid + 1;
00505 }
00506
00507 return 0;
00508 }
00509
00510
00511
00512 static int get_maxnode (void *vface, void *vmaxnode)
00513 {
00514 FACE *face = (FACE *)vface;
00515 int n, *maxnode = (int *)vmaxnode;
00516
00517 for (n = 0; n < face->nnodes; n++) {
00518 if (*maxnode < face->nodes[n]) *maxnode = face->nodes[n];
00519 }
00520 return 0;
00521 }
00522
00523
00524
00525 static int get_extnodes (void *vface, void *vnodes)
00526 {
00527 FACE *face = (FACE *)vface;
00528
00529 if (face->e2 == 0) {
00530 int n, *nodes = (int *)vnodes;
00531 for (n = 0; n < face->nnodes; n++)
00532 nodes[face->nodes[n]-1] = 1;
00533 }
00534 return 0;
00535 }
00536
00537
00538
00539 static int valid_face (ZONE *z, int elem)
00540 {
00541 int n, ns, nn, ne, *pe;
00542 ElementType_t type;
00543
00544 for (ns = 0; ns < z->nsets; ns++) {
00545 if (z->sets[ns].invalid || z->sets[ns].ns == 0) continue;
00546 if (elem >= z->sets[ns].is && elem <= z->sets[ns].ie) {
00547 type = z->sets[ns].type;
00548 pe = z->sets[ns].elements;
00549 ne = elem - z->sets[ns].is;
00550 #if CGNS_VERSION >= 3000
00551 if (type == NGON_n) {
00552 for (n = 0; n < ne; n++) {
00553 nn = *pe++;
00554 pe += nn;
00555 }
00556 return (*pe < 3 ? 0 : 1);
00557 }
00558 #endif
00559 if (type == MIXED) {
00560 for (n = 0; n < ne; n++) {
00561 type = (ElementType_t)*pe++;
00562 if (type >= NGON_n) {
00563 nn = (int)(type - NGON_n);
00564 }
00565 else {
00566 if (cg_npe (type, &nn) || nn <= 0) return 0;
00567 }
00568 pe += nn;
00569 }
00570 type = (ElementType_t)*pe;
00571 if (type >= NGON_n+3) return 1;
00572 }
00573 if (type >= TRI_3 && type <= QUAD_9) return 1;
00574 return 0;
00575 }
00576 }
00577 return 0;
00578 }
00579
00580
00581
00582 static int *find_element (ZONE *z, int elem, int *dim, int *nnodes)
00583 {
00584 int ns, nn, ne, *nodes;
00585 ElementType_t type;
00586
00587 for (ns = 0; ns < z->nsets; ns++) {
00588 if (z->sets[ns].invalid) continue;
00589 if (elem >= z->sets[ns].is && elem <= z->sets[ns].ie) {
00590 ne = elem - z->sets[ns].is;
00591 nodes = z->sets[ns].elements;
00592 type = z->sets[ns].type;
00593 #if CGNS_VERSION >= 3000
00594 if (type == NGON_n) {
00595 while (ne-- > 0) {
00596 nn = *nodes++;
00597 nodes += nn;
00598 }
00599 *dim = 2;
00600 *nnodes = *nodes++;
00601 return nodes;
00602 }
00603 if (type == NFACE_n) {
00604 while (ne-- > 0) {
00605 nn = *nodes++;
00606 nodes += nn;
00607 }
00608 *dim = 3;
00609 *nnodes = *nodes++;
00610 return nodes;
00611 }
00612 #endif
00613 cg_npe (type, &nn);
00614 if (nn) {
00615 nodes += (nn * ne);
00616 }
00617 else if (type == MIXED) {
00618 type = *nodes++;
00619 while (ne-- > 0) {
00620 if (type >= NGON_n)
00621 nn = (int)(type - NGON_n);
00622 else {
00623 if (cg_npe (type, &nn) || nn <= 0)
00624 return NULL;
00625 }
00626 nodes += nn;
00627 type = *nodes++;
00628 }
00629 }
00630 else {
00631 return NULL;
00632 }
00633 if (type == NODE)
00634 *dim = 0;
00635 else if (type < TRI_3)
00636 *dim = 1;
00637 else if (type < TETRA_4 || type >= NGON_n)
00638 *dim = 2;
00639 else {
00640 *dim = 3;
00641 if (type == HEXA_27) nn--;
00642 }
00643 #ifndef USE_MID_NODES
00644 switch (type) {
00645 case QUAD_9:
00646 case PYRA_14:
00647 nn--;
00648 break;
00649 case PENTA_18:
00650 nn -= 3;
00651 break;
00652 case HEXA_27:
00653 nn -= 6;
00654 break;
00655 }
00656 #endif
00657 *nnodes = nn;
00658 return nodes;
00659 }
00660 }
00661 return NULL;
00662 }
00663
00664
00665
00666 static FACE *new_face (int nnodes, int *nodes)
00667 {
00668 FACE *f = (FACE *) malloc (sizeof(FACE) + nnodes * sizeof(int));
00669 if (f == NULL) {
00670 fprintf (stderr, "malloc failed for a new face\n");
00671 exit (1);
00672 }
00673 f->e1 = f->e2 = f->f1 = f->f2 = 0;
00674 f->nnodes = nnodes;
00675 f->nodes = (int *)(f + 1);
00676 if (nodes != NULL) {
00677 int n;
00678 for (n = 0; n < nnodes; n++)
00679 f->nodes[n] = nodes[n];
00680 qsort (f->nodes, f->nnodes, sizeof(int), sort_nodes);
00681 }
00682 return f;
00683 }
00684
00685
00686
00687 static int tetra_4[4][4] = {
00688 {3, 0, 2, 1},
00689 {3, 0, 1, 3},
00690 {3, 1, 2, 3},
00691 {3, 2, 0, 3}
00692 };
00693 static int tetra_10[4][7] = {
00694 {6, 0, 6, 2, 5, 1, 4},
00695 {6, 0, 4, 1, 8, 3, 7},
00696 {6, 1, 5, 2, 9, 3, 8},
00697 {6, 2, 6, 0, 7, 3, 9}
00698 };
00699 static int pyra_5[5][5] = {
00700 {4, 0, 3, 2, 1},
00701 {3, 0, 1, 4, 0},
00702 {3, 1, 2, 4, 0},
00703 {3, 2, 3, 4, 0},
00704 {3, 3, 0, 4, 0}
00705 };
00706 static int pyra_13[5][9] = {
00707 {8, 0, 8, 3, 7, 2, 6, 1, 5},
00708 {6, 0, 5, 1, 10, 4, 9, 0, 0},
00709 {6, 1, 6, 2, 11, 4, 10, 0, 0},
00710 {6, 2, 7, 3, 12, 4, 11, 0, 0},
00711 {6, 3, 8, 0, 9, 4, 12, 0, 0}
00712 };
00713 static int pyra_14[5][10] = {
00714 {9, 0, 8, 3, 7, 2, 6, 1, 5, 13},
00715 {6, 0, 5, 1, 10, 4, 9, 0, 0, 0},
00716 {6, 1, 6, 2, 11, 4, 10, 0, 0, 0},
00717 {6, 2, 7, 3, 12, 4, 11, 0, 0, 0},
00718 {6, 3, 8, 0, 9, 4, 12, 0, 0, 0}
00719 };
00720 static int penta_6[5][5] = {
00721 {4, 0, 1, 4, 3},
00722 {4, 1, 2, 5, 4},
00723 {4, 2, 0, 3, 5},
00724 {3, 0, 2, 1, 0},
00725 {3, 3, 4, 5, 0},
00726 };
00727 static int penta_15[5][9] = {
00728 {8, 0, 6, 1, 10, 4, 12, 3, 9},
00729 {8, 1, 7, 2, 11, 5, 13, 4, 10},
00730 {8, 2, 8, 0, 9, 3, 14, 5, 11},
00731 {6, 0, 8, 2, 7, 1, 6, 0, 0},
00732 {6, 3, 12, 4, 13, 5, 14, 0, 0},
00733 };
00734 static int penta_18[5][10] = {
00735 {9, 0, 6, 1, 10, 4, 12, 3, 9, 15},
00736 {9, 1, 7, 2, 11, 5, 13, 4, 10, 16},
00737 {9, 2, 8, 0, 9, 3, 14, 5, 11, 17},
00738 {6, 0, 8, 2, 7, 1, 6, 0, 0, 0},
00739 {6, 3, 12, 4, 13, 5, 14, 0, 0, 0},
00740 };
00741 static int hexa_8[6][5] = {
00742 {4, 0, 3, 2, 1},
00743 {4, 0, 1, 5, 4},
00744 {4, 1, 2, 6, 5},
00745 {4, 2, 3, 7, 6},
00746 {4, 0, 4, 7, 3},
00747 {4, 4, 5, 6, 7}
00748 };
00749 static int hexa_20[6][9] = {
00750 {8, 0, 11, 3, 10, 2, 9, 1, 8},
00751 {8, 0, 8, 1, 13, 5, 16, 4, 12},
00752 {8, 1, 9, 2, 14, 6, 17, 5, 13},
00753 {8, 2, 10, 3, 15, 7, 18, 6, 14},
00754 {8, 0, 12, 4, 19, 7, 15, 3, 11},
00755 {8, 4, 16, 5, 17, 6, 18, 7, 19}
00756 };
00757 static int hexa_27[6][10] = {
00758 {9, 0, 11, 3, 10, 2, 9, 1, 8, 20},
00759 {9, 0, 8, 1, 13, 5, 16, 4, 12, 21},
00760 {9, 1, 9, 2, 14, 6, 17, 5, 13, 22},
00761 {9, 2, 10, 3, 15, 7, 18, 6, 14, 23},
00762 {9, 0, 12, 4, 19, 7, 15, 3, 11, 24},
00763 {9, 4, 16, 5, 17, 6, 18, 7, 19, 25}
00764 };
00765
00766 static FACE *element_face (ZONE *z, int fnum, ElementType_t type, int *nodes)
00767 {
00768 int n, *nodemap;
00769 FACE *face;
00770
00771 #if CGNS_VERSION >= 3000
00772 if (type == NFACE_n) {
00773 int dim;
00774 nodemap = find_element (z, nodes[fnum], &dim, &n);
00775 if (nodemap == NULL || dim != 2) {
00776 fprintf (stderr, "INTERNAL:find_element returned invalid face\n");
00777 exit (1);
00778 }
00779 return new_face (n, nodemap);
00780 }
00781 #endif
00782 switch (type) {
00783 case TETRA_4:
00784 nodemap = tetra_4[fnum];
00785 break;
00786 case TETRA_10:
00787 nodemap = tetra_10[fnum];
00788 break;
00789 case PYRA_5:
00790 nodemap = pyra_5[fnum];
00791 break;
00792 #if CGNS_VERSION >= 3000
00793 case PYRA_13:
00794 nodemap = pyra_13[fnum];
00795 break;
00796 #endif
00797 case PYRA_14:
00798 #ifdef USE_MID_NODES
00799 nodemap = pyra_14[fnum];
00800 #else
00801 nodemap = pyra_13[fnum];
00802 #endif
00803 break;
00804 case PENTA_6:
00805 nodemap = penta_6[fnum];
00806 break;
00807 case PENTA_15:
00808 nodemap = penta_15[fnum];
00809 break;
00810 case PENTA_18:
00811 #ifdef USE_MID_NODES
00812 nodemap = penta_18[fnum];
00813 #else
00814 nodemap = penta_15[fnum];
00815 #endif
00816 break;
00817 case HEXA_8:
00818 nodemap = hexa_8[fnum];
00819 break;
00820 case HEXA_20:
00821 nodemap = hexa_20[fnum];
00822 break;
00823 case HEXA_27:
00824 #ifdef USE_MID_NODES
00825 nodemap = hexa_27[fnum];
00826 #else
00827 nodemap = hexa_20[fnum];
00828 #endif
00829 break;
00830 default:
00831 fprintf (stderr, "INTERNAL:invalid element type in element_face\n");
00832 exit (1);
00833 }
00834 face = new_face (*nodemap++, NULL);
00835 for (n = 0; n < face->nnodes; n++)
00836 face->nodes[n] = nodes[nodemap[n]];
00837 qsort (face->nodes, face->nnodes, sizeof(int), sort_nodes);
00838 return face;
00839 }
00840
00841
00842
00843 static int compare_elemsets (const void *e1, const void *e2)
00844 {
00845 return (((ELEMSET *)e1)->is - ((ELEMSET *)e2)->is);
00846 }
00847
00848
00849
00850
00851
00852
00853 static void read_zone (int nz)
00854 {
00855 char name[33];
00856 int i, j, n, size[9];
00857 int ns, nsets, hasparent;
00858 int ne, nelem, *pe;
00859 int nn, nf, ip, type, ierr;
00860 int *nodes, maxnode;
00861 ELEMSET *es;
00862 ZoneType_t zonetype;
00863 ZONE *z = &Zones[nz++];
00864 FACE *face, *pf;
00865
00866 if (cg_zone_read (cgnsfn, cgnsbase, nz, name, size))
00867 error_exit("cg_zone_read");
00868 if (cg_zone_type (cgnsfn, cgnsbase, nz, &zonetype))
00869 error_exit("cg_zone_type");
00870
00871 printf ("reading zone \"%s\"\n", name);
00872 fflush (stdout);
00873
00874 strcpy (z->name, name);
00875 z->type = zonetype;
00876 z->idim = z->nnodes = 0;
00877 z->nsets = z->nextnodes = 0;
00878 z->nv = z->ns = z->ne = z->nn = 0;
00879 z->faces = NULL;
00880
00881 for (j = 0; j < 3; j++)
00882 for (i = 0; i < 3; i++)
00883 z->dims[j][i] = 0;
00884
00885 if (zonetype == Structured) {
00886 z->idim = CellDim;
00887 for (n = 0, j = 0; j < 3; j++) {
00888 for (i = 0; i < CellDim; i++) {
00889 z->dims[j][i] = size[n++];
00890 }
00891 }
00892 }
00893 else if (zonetype == Unstructured) {
00894 z->idim = 1;
00895 for (n = 0; n < 3; n++)
00896 z->dims[n][0] = size[n];
00897 }
00898 else {
00899 return;
00900 }
00901
00902 for (z->nnodes = 1, n = 0; n < z->idim; n++)
00903 z->nnodes *= z->dims[0][n];
00904 z->maxnode = z->nnodes;
00905
00906
00907
00908 if (cg_nsections (cgnsfn, cgnsbase, nz, &nsets))
00909 error_exit ("cg_nsections");
00910 if (z->type == Structured) {
00911 if (nsets)
00912 warning (1, "element sets are not used with Structured grid");
00913 return;
00914 }
00915 if (!nsets) {
00916 if (size[1]) error ("no element sets found");
00917 return;
00918 }
00919 z->nsets = nsets;
00920 z->sets = (ELEMSET *) malloc (nsets * sizeof(ELEMSET));
00921 if (NULL == z->sets) {
00922 fprintf (stderr, "malloc failed for element sets\n");
00923 exit (1);
00924 }
00925
00926
00927
00928 for (es = z->sets, ns = 1; ns <= nsets; ns++, es++) {
00929 es->invalid = 0;
00930 if (cg_section_read (cgnsfn, cgnsbase, nz, ns, es->name,
00931 &es->type, &es->is, &es->ie, &es->ib, &hasparent))
00932 error_exit("cg_section_read");
00933 printf (" reading element set \"%s\"\n", es->name);
00934 fflush (stdout);
00935 nelem = es->ie - es->is + 1;
00936 if (cg_ElementDataSize (cgnsfn, cgnsbase, nz, ns, &nn))
00937 error_exit ("cg_ElementDataSize");
00938 if (nn == 0) continue;
00939 es->elements = (int *) malloc (nn * sizeof(int));
00940 if (NULL == es->elements) {
00941 fprintf (stderr, "malloc failed for elements\n");
00942 exit (1);
00943 }
00944 es->parent = NULL;
00945 if (hasparent) {
00946 es->parent = (int *) malloc (4 * nelem * sizeof(int));
00947 if (NULL == es->parent) {
00948 fprintf (stderr, "malloc failed for elemset parent data\n");
00949 exit (1);
00950 }
00951 }
00952 if (cg_elements_read (cgnsfn, cgnsbase, nz, ns, es->elements,
00953 es->parent)) error_exit ("cg_elements_read");
00954
00955 go_absolute ("Zone_t", nz, "Elements_t", ns, NULL);
00956 ierr = read_rind (es->rind);
00957 if (ierr) {
00958 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_rind_read");
00959 es->rind[0] = es->rind[1] = 0;
00960 }
00961 else {
00962 if (FileVersion < 2400)
00963 error ("rind not valid for elements");
00964 }
00965
00966 es->nv = es->ns = es->ne = es->nn = 0;
00967 #if CGNS_VERSION >= 3000
00968 if (es->type < NODE) {
00969 #else
00970 if (es->type < NODE || es->type > MIXED) {
00971 #endif
00972 es->invalid = -1;
00973 continue;
00974 }
00975 if (es->type == MIXED) {
00976 ip = ierr = 0;
00977 for (pe = es->elements, ne = 0; ne < nelem; ne++) {
00978 type = *pe++;
00979 if (type < NODE || type == MIXED) {
00980 if (type == MIXED)
00981 es->invalid = -2;
00982 else
00983 es->invalid = -1;
00984 break;
00985 }
00986 if (type >= NGON_n) {
00987 ip++;
00988 nn = type - NGON_n;
00989 if (nn < 3) {
00990 ierr++;
00991 }
00992 else {
00993 (es->ns)++;
00994 if (ne >= es->rind[0] && ne < nelem - es->rind[1])
00995 (z->ns)++;
00996 }
00997 pe += nn;
00998 continue;
00999 }
01000 if (type == NODE) {
01001 (es->nn)++;
01002 if (ne >= es->rind[0] && ne < nelem - es->rind[1])
01003 (z->nn)++;
01004 }
01005 else if (type <= BAR_3) {
01006 (es->ne)++;
01007 if (ne >= es->rind[0] && ne < nelem - es->rind[1])
01008 (z->ne)++;
01009 }
01010 else if (type <= QUAD_9) {
01011 (es->ns)++;
01012 if (ne >= es->rind[0] && ne < nelem - es->rind[1])
01013 (z->ns)++;
01014 }
01015 else {
01016 (es->nv)++;
01017 if (ne >= es->rind[0] && ne < nelem - es->rind[1])
01018 (z->nv)++;
01019 }
01020 if (cg_npe (type, &nn) || nn <= 0) {
01021 es->invalid = -3;
01022 break;
01023 }
01024 pe += nn;
01025 }
01026 if (ierr)
01027 warning (2, "%d NGON_n element with < 3 nodes in MIXED", ierr);
01028 if (ip) {
01029 if (FileVersion >= 3000)
01030 warning (2,
01031 "NGON_n in MIXED deprecated - use NGON_n element set");
01032 }
01033 }
01034 #if CGNS_VERSION >= 3000
01035 else if (es->type == NGON_n) {
01036 es->ns = nelem;
01037 z->ns += (nelem - es->rind[0] - es->rind[1]);
01038 }
01039 else if (es->type == NFACE_n) {
01040 es->nv = nelem;
01041 z->nv += (nelem - es->rind[0] - es->rind[1]);
01042 }
01043 #endif
01044 else if (es->type == NODE) {
01045 es->nn = nelem;
01046 z->nn += (nelem - es->rind[0] - es->rind[1]);
01047 }
01048 else if (es->type <= BAR_3) {
01049 es->ne = nelem;
01050 z->ne += (nelem - es->rind[0] - es->rind[1]);
01051 }
01052 else if (es->type <= QUAD_9) {
01053 es->ns = nelem;
01054 z->ns += (nelem - es->rind[0] - es->rind[1]);
01055 }
01056 else {
01057 es->nv = nelem;
01058 z->nv += (nelem - es->rind[0] - es->rind[1]);
01059 }
01060 }
01061
01062
01063
01064 if (nsets > 1)
01065 qsort (z->sets, nsets, sizeof(ELEMSET), compare_elemsets);
01066
01067 if (!z->nv) return;
01068
01069
01070
01071 ierr = 0;
01072 for (es = z->sets, ns = 0; ns < nsets; ns++, es++) {
01073 if (es->invalid || es->nv == 0) continue;
01074 nelem = es->ie - es->is + 1 - es->rind[1];
01075 pe = es->elements;
01076 if (es->type == MIXED) {
01077 for (ne = 0; ne < nelem; ne++) {
01078 type = *pe++;
01079 if (type >= NGON_n)
01080 nn = (int)(type - NGON_n);
01081 else
01082 cg_npe (type, &nn);
01083 if (nn <= 0) {
01084 es->invalid = -3;
01085 break;
01086 }
01087 if (ne >= es->rind[0]) {
01088 for (i = 0; i < nn; i++) {
01089 if (pe[i] < 1 || pe[i] > z->nnodes) {
01090 ierr++;
01091 (es->invalid)++;
01092 }
01093 }
01094 }
01095 pe += nn;
01096 }
01097 }
01098 #if CGNS_VERSION >= 3000
01099 else if (es->type == NGON_n) {
01100 for (ne = 0; ne < nelem; ne++) {
01101 nn = *pe++;
01102 if (ne >= es->rind[0]) {
01103 for (i = 0; i < nn; i++) {
01104 if (pe[i] < 1 || pe[i] > z->maxnode) {
01105 ierr++;
01106 (es->invalid)++;
01107 }
01108 }
01109 }
01110 pe += nn;
01111 }
01112 }
01113 else if (es->type == NFACE_n) {
01114 for (ne = 0; ne < nelem; ne++) {
01115 nn = *pe++;
01116 if (ne >= es->rind[0]) {
01117 for (i = 0; i < nn; i++) {
01118 if (!valid_face (z, pe[i])) {
01119 ierr++;
01120 (es->invalid)++;
01121 }
01122 }
01123 }
01124 pe += nn;
01125 }
01126 }
01127 #endif
01128 else {
01129 if (cg_npe (es->type, &nn) || nn <= 0) {
01130 es->invalid = -3;
01131 continue;
01132 }
01133 if (es->rind[0] > 0) {
01134 nelem -= es->rind[0];
01135 pe += (nn * es->rind[0]);
01136 }
01137 nn *= nelem;
01138 for (i = 0; i < nn; i++) {
01139 if (pe[i] < 1 || pe[i] > z->nnodes) {
01140 ierr++;
01141 (es->invalid)++;
01142 }
01143 }
01144 }
01145 }
01146
01147
01148
01149 if (ierr) {
01150 printf(" skipping volume face checking since there were %d errors\n",
01151 ierr);
01152 return;
01153 }
01154 puts (" building volume faces hash table...");
01155 fflush (stdout);
01156 nn = (z->nv >> 2) + 1;
01157 z->faces = HashCreate (nn, compare_faces, hash_face);
01158 if (z->faces == NULL) {
01159 fprintf (stderr, "malloc failed for face hash table\n");
01160 exit (1);
01161 }
01162
01163 ierr = 0;
01164 for (es = z->sets, ns = 0; ns < nsets; ns++, es++) {
01165 if (es->invalid || es->nv == 0 || es->type < TETRA_4) continue;
01166 if (es->type > MIXED) {
01167 #if CGNS_VERSION >= 3000
01168 if (es->type != NFACE_n)
01169 #endif
01170 continue;
01171 }
01172 nelem = es->ie - es->is + 1 - es->rind[1];
01173 type = es->type;
01174 pe = es->elements;
01175 cg_npe (es->type, &nn);
01176
01177 for (ne = 0; ne < nelem; ne++) {
01178 if (es->type == MIXED) {
01179 type = *pe++;
01180 if (type >= NGON_n)
01181 nn = (int)(type - NGON_n);
01182 else
01183 cg_npe (type, &nn);
01184 }
01185 switch (type) {
01186 case TETRA_4:
01187 case TETRA_10:
01188 nf = 4;
01189 break;
01190 case PYRA_5:
01191 #if CGNS_VERSION >= 3000
01192 case PYRA_13:
01193 #endif
01194 case PYRA_14:
01195 case PENTA_6:
01196 case PENTA_15:
01197 case PENTA_18:
01198 nf = 5;
01199 break;
01200 case HEXA_8:
01201 case HEXA_20:
01202 case HEXA_27:
01203 nf = 6;
01204 break;
01205 case NFACE_n:
01206 nf = *pe++;
01207 nn = nf;
01208 break;
01209 default:
01210 nf = 0;
01211 break;
01212 }
01213 if (nf > 0 && ne >= es->rind[0]) {
01214 for (j = 0; j < nf; j++) {
01215 face = element_face (z, j, type, pe);
01216 pf = (FACE *) HashFind (z->faces, face);
01217 if (pf == NULL) {
01218 face->e1 = es->is + ne;
01219 face->f1 = j + 1;
01220 (void) HashAdd (z->faces, face);
01221 }
01222 else if (pf->e2) {
01223 ierr++;
01224 }
01225 else {
01226 pf->e2 = es->is + ne;
01227 pf->f2 = j + 1;
01228 }
01229 }
01230 }
01231 pe += nn;
01232 }
01233 }
01234
01235 if (ierr)
01236 warning (1, "%d faces are shared by more than 2 volumes", ierr);
01237
01238
01239
01240 puts (" finding exterior nodes...");
01241 fflush (stdout);
01242 maxnode = 0;
01243 HashList (z->faces, get_maxnode, &maxnode);
01244 nodes = (int *) calloc (maxnode, sizeof(int));
01245 if (nodes == NULL) {
01246 fprintf (stderr, "malloc failed for zone nodes\n");
01247 exit (1);
01248 }
01249 HashList (z->faces, get_extnodes, nodes);
01250 for (nn = 0, n = 0; n < z->nnodes; n++) {
01251 if (nodes[n]) nn++;
01252 }
01253 z->nextnodes = nn;
01254 z->extnodes = (int *) malloc (nn * sizeof(int));
01255 if (z->extnodes == NULL) {
01256 fprintf (stderr, "malloc failed for zone exterior nodes\n");
01257 exit (1);
01258 }
01259 for (nn = 0, n = 0; n < z->nnodes; n++) {
01260 if (nodes[n]) z->extnodes[nn++] = n + 1;
01261 }
01262 free (nodes);
01263 }
01264
01265
01266
01267 static int get_data_size (ZONE *z, GridLocation_t location, int *rind)
01268 {
01269 int n, i, datasize = 1;
01270
01271 if (location == Vertex) {
01272 for (n = 0, i = 0; i < z->idim; i++) {
01273 datasize *= (z->dims[0][i] + rind[n] + rind[n+1]);
01274 n += 2;
01275 }
01276 return datasize;
01277 }
01278
01279 if (location == CellCenter) {
01280 for (n = 0, i = 0; i < z->idim; i++) {
01281 datasize *= (z->dims[1][i] + rind[n] + rind[n+1]);
01282 n += 2;
01283 }
01284 return datasize;
01285 }
01286
01287 if (z->type == Unstructured) {
01288 error ("grid location %s not valid for unstructured zone",
01289 cg_GridLocationName (location));
01290 return 0;
01291 }
01292
01293 if (location == FaceCenter) {
01294 if (z->idim > 2) {
01295 error ("location is FaceCenter but index dimension > 2");
01296 return 0;
01297 }
01298 for (n = 0, i = 0; i < z->idim; i++) {
01299 datasize *= (z->dims[1][i] + rind[n] + rind[n+1]);
01300 n += 2;
01301 }
01302 return datasize;
01303 }
01304
01305 if (location == EdgeCenter) {
01306 if (z->idim > 1) {
01307 error ("location is EdgeCenter but index dimension > 1");
01308 return 0;
01309 }
01310 datasize = z->dims[1][0] + rind[0] + rind[1];
01311 return datasize;
01312 }
01313
01314 if (location == IFaceCenter) {
01315 for (n = 0, i = 1; i < z->idim; i++) {
01316 if (i == 0)
01317 datasize *= (z->dims[0][i] + rind[n] + rind[n+1]);
01318 else
01319 datasize *= (z->dims[1][i] + rind[n] + rind[n+1]);
01320 n += 2;
01321 }
01322 return datasize;
01323 }
01324
01325 if (location == JFaceCenter) {
01326 if (z->idim < 2) {
01327 error ("location is JFaceCenter but index dimension < 2");
01328 return 0;
01329 }
01330 for (n = 0, i = 1; i < z->idim; i++) {
01331 if (i == 1)
01332 datasize *= (z->dims[0][i] + rind[n] + rind[n+1]);
01333 else
01334 datasize *= (z->dims[1][i] + rind[n] + rind[n+1]);
01335 n += 2;
01336 }
01337 return datasize;
01338 }
01339
01340 if (location == KFaceCenter) {
01341 if (z->idim < 3) {
01342 error ("location is KFaceCenter but index dimension < 3");
01343 return 0;
01344 }
01345 for (n = 0, i = 1; i < z->idim; i++) {
01346 if (i == 2)
01347 datasize *= (z->dims[0][i] + rind[n] + rind[n+1]);
01348 else
01349 datasize *= (z->dims[1][i] + rind[n] + rind[n+1]);
01350 n += 2;
01351 }
01352 return datasize;
01353 }
01354
01355 error ("grid location %s is invalid", cg_GridLocationName(location));
01356 return 0;
01357 }
01358
01359
01360
01361 static int read_dataclass (void)
01362 {
01363 int ierr;
01364 DataClass_t dataclass;
01365
01366 ierr = cg_dataclass_read (&dataclass);
01367 if (ierr) {
01368 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_dataclass_read");
01369 return -1;
01370 }
01371 return (int)dataclass;
01372 }
01373
01374
01375
01376 static int *read_units (int units[9])
01377 {
01378 int n, ierr;
01379 MassUnits_t mass;
01380 LengthUnits_t length;
01381 TimeUnits_t time;
01382 TemperatureUnits_t temp;
01383 AngleUnits_t angle;
01384 #if CGNS_VERSION >= 2400
01385 ElectricCurrentUnits_t current;
01386 SubstanceAmountUnits_t amount;
01387 LuminousIntensityUnits_t intensity;
01388 #endif
01389
01390 for (n = 0; n < 9; n++)
01391 units[n] = 0;
01392 #if CGNS_VERSION >= 2400
01393 ierr = cg_unitsfull_read (&mass, &length, &time, &temp, &angle,
01394 ¤t, &amount, &intensity);
01395 if (ierr) {
01396 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_unitsfull_read");
01397 return NULL;
01398 }
01399 cg_nunits (&n);
01400 units[8] = n;
01401 units[5] = current;
01402 units[6] = amount;
01403 units[7] = intensity;
01404 #else
01405 ierr = cg_units_read (&mass, &length, &time, &temp, &angle);
01406 if (ierr) {
01407 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_units_read");
01408 return NULL;
01409 }
01410 units[8] = 5;
01411 #endif
01412 units[0] = mass;
01413 units[1] = length;
01414 units[2] = time;
01415 units[3] = temp;
01416 units[4] = angle;
01417 return units;
01418 }
01419
01420
01421
01422 static int read_exponents (float exps[9])
01423 {
01424 int n, ierr;
01425 DataType_t type;
01426
01427 for (n = 0; n < 9; n++)
01428 exps[n] = 0;
01429 ierr = cg_exponents_info (&type);
01430 if (ierr) {
01431 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_exponents_info");
01432 return 0;
01433 }
01434 if (type == RealSingle)
01435 #if CGNS_VERSION >= 2400
01436 ierr = cg_expfull_read (exps);
01437 #else
01438 ierr = cg_exponents_read (exps);
01439 #endif
01440 else if (type == RealDouble) {
01441 #if CGNS_VERSION >= 2400
01442 double data[8];
01443 ierr = cg_expfull_read (data);
01444 if (ierr == CG_OK) {
01445 for (n = 0; n < 8; n++)
01446 exps[n] = (float)data[n];
01447 }
01448 #else
01449 double data[5];
01450 ierr = cg_exponents_read (data);
01451 if (ierr == CG_OK) {
01452 for (n = 0; n < 5; n++)
01453 exps[n] = (float)data[n];
01454 }
01455 #endif
01456 }
01457 else {
01458 fprintf (stderr, "invalid data type for exponents\n");
01459 exit (1);
01460 }
01461 if (ierr) {
01462 if (ierr != CG_NODE_NOT_FOUND)
01463 #if CGNS_VERSION >= 2400
01464 error_exit("cg_expfull_read");
01465 #else
01466 error_exit("cg_exponents_read");
01467 #endif
01468 return 0;
01469 }
01470 #if CGNS_VERSION >= 2400
01471 cg_nexponents (&n);
01472 exps[8] = n;
01473 #else
01474 exps[8] = 5;
01475 #endif
01476 return 1;
01477 }
01478
01479
01480
01481 static void print_indent (int indent)
01482 {
01483 while (indent-- > 0) putchar (' ');
01484 }
01485
01486
01487
01488 static void print_dataclass (int dataclass, int indent)
01489 {
01490 print_indent (indent);
01491 printf ("Data Class=");
01492 if (dataclass < 0)
01493 puts ("<not specified>");
01494 else
01495 puts (cg_DataClassName(dataclass));
01496 }
01497
01498
01499
01500 static void print_units (int *units, int indent)
01501 {
01502 print_indent (indent);
01503 #if CGNS_VERSION >= 2400
01504 printf ("Units=[%s,%s,%s,%s,%s",
01505 cg_MassUnitsName(units[0]),
01506 cg_LengthUnitsName(units[1]),
01507 cg_TimeUnitsName(units[2]),
01508 cg_TemperatureUnitsName(units[4]),
01509 cg_AngleUnitsName(units[4]));
01510 if (units[8] > 5)
01511 printf (",%s,%s,%s",
01512 cg_ElectricCurrentUnitsName(units[5]),
01513 cg_SubstanceAmountUnitsName(units[6]),
01514 cg_LuminousIntensityUnitsName(units[7]));
01515 puts ("]");
01516 #else
01517 printf ("Units=[%s,%s,%s,%s,%s]\n",
01518 cg_MassUnitsName(units[0]),
01519 cg_LengthUnitsName(units[1]),
01520 cg_TimeUnitsName(units[2]),
01521 cg_TemperatureUnitsName(units[4]),
01522 cg_AngleUnitsName(units[4]));
01523 #endif
01524 }
01525
01526
01527
01528 static void print_exponents (float *exps, int indent)
01529 {
01530 print_indent (indent);
01531 #if CGNS_VERSION >= 2400
01532 printf ("Exponents=[%g,%g,%g,%g,%g", exps[0], exps[1],
01533 exps[2], exps[3], exps[4]);
01534 if (exps[8] > 5.0)
01535 printf (",%g,%g,%g", exps[5], exps[6], exps[7]);
01536 puts ("]");
01537 #else
01538 printf ("Exponents=[%g,%g,%g,%g,%g]\n", exps[0], exps[1],
01539 exps[2], exps[3], exps[4]);
01540 #endif
01541 }
01542
01543
01544
01545 static void check_quantity (int dnum, char *name,
01546 int parclass, int *parunits, int isref, int indent)
01547 {
01548 int n, ne, dclass, *punits, hasexps, units[9];
01549 float defexps[8], exps[9];
01550
01551 go_relative ("DataArray_t", dnum, NULL);
01552 dclass = read_dataclass ();
01553 punits = read_units (units);
01554 hasexps = read_exponents (exps);
01555 go_relative ("..", 1, NULL);
01556
01557 if (verbose) {
01558 if (dclass >= 0) print_dataclass (dclass, indent);
01559 if (punits != NULL) print_units (punits, indent);
01560 if (hasexps) print_exponents (exps, indent);
01561 }
01562 if (dclass < 0) dclass = parclass;
01563
01564 if (cg_get_identifier (name, &ne, defexps)) {
01565 if (isref > 0)
01566 warning (3, "not a CGNS data-name identifier");
01567 if (dclass < 0)
01568 warning (3, "dataclass is not given");
01569 else if ((DataClass_t)dclass == Dimensional) {
01570 if (punits == NULL && parunits == NULL)
01571 warning (2, "units not given");
01572 if (!hasexps)
01573 warning (2, "exponents not given");
01574 }
01575 else {
01576 if (punits != NULL || hasexps)
01577 warning (2, "dataclass is %s, but units and/or exponents"
01578 " are given", cg_DataClassName(dclass));
01579 }
01580 return;
01581 }
01582
01583 if (isref < 0) return;
01584
01585 if (dclass < 0)
01586 warning (2, "dataclass not given");
01587 else if ((DataClass_t)dclass == Dimensional ||
01588 (DataClass_t)dclass == NormalizedByDimensional ||
01589 (DataClass_t)dclass == NormalizedByUnknownDimensional) {
01590 if (!ne)
01591 warning (2, "dataclass does not match CGNS specification");
01592 if ((DataClass_t)dclass == Dimensional &&
01593 punits == NULL && parunits == NULL)
01594 warning (2, "units not given for dimensional quantity");
01595 if (hasexps && ne > 0) {
01596 for (n = 0; n < ne; n++) {
01597 if (exps[n] != defexps[n]) break;
01598 }
01599 if (n < ne)
01600 warning (2, "exponents do not match CGNS specification");
01601 }
01602 }
01603 else if ((DataClass_t)dclass == NondimensionalParameter ||
01604 (DataClass_t)dclass == DimensionlessConstant) {
01605 if (ne)
01606 warning (2, "dataclass does not match CGNS specification");
01607 if (punits != NULL)
01608 warning (2, "units given for nondimensional quantity");
01609 if (hasexps)
01610 warning (2, "exponents given for nondimensional quantity");
01611 }
01612 else
01613 error ("invalid dataclass");
01614 }
01615
01616
01617
01618 static void check_arrays (int parclass, int *parunits, int isref,
01619 int length, int indent)
01620 {
01621 int n, narrays, na, ndim, dims[12];
01622 int dataclass, *punits, units[9], size;
01623 DataType_t datatype;
01624 char name[33];
01625
01626 dataclass = read_dataclass ();
01627 punits = read_units (units);
01628 if (verbose) {
01629 if (dataclass >= 0) print_dataclass (dataclass, indent);
01630 if (punits) print_units (punits, indent);
01631 }
01632 if (dataclass < 0) dataclass = parclass;
01633 if (!punits) punits = parunits;
01634
01635 if (cg_narrays (&narrays)) error_exit ("cg_narrays");
01636
01637 for (na = 1; na <= narrays; na++) {
01638 if (cg_array_info (na, name, &datatype, &ndim, dims))
01639 error_exit ("cg_array_info");
01640 print_indent (indent);
01641 printf ("checking quantity \"%s\"\n", name);
01642 fflush (stdout);
01643 for (size = 1, n = 0; n < ndim; n++)
01644 size *= dims[n];
01645 if (ndim < 1 || size < 1)
01646 error ("invalid dimensions");
01647 if (length < 0 && size != 1 && size != -length)
01648 error ("array size not 1 or %d", -length);
01649 if (length > 0 && size != length)
01650 error ("array size not %d", length);
01651 check_quantity (na, name, dataclass, punits, isref, indent+2);
01652 }
01653 }
01654
01655
01656
01657 static void check_user_data (int parclass, int *parunits, int indent)
01658 {
01659 int n, nd, nu, nuser, na, ndim, dims[12];
01660 int dataclass, *punits, units[9];
01661 char name[33], *desc;
01662 DataType_t datatype;
01663 #if CGNS_VERSION >= 2400
01664 GridLocation_t location;
01665 PointSetType_t ptype;
01666 int hasf, haso, hasl, hasp, npnts, ordinal;
01667 #endif
01668
01669 if (cg_nuser_data (&nuser)) error_exit ("cg_nuser_data");
01670 if (nuser <= 0) return;
01671
01672 for (nu = 1; nu <= nuser; nu++) {
01673 if (cg_user_data_read (nu, name)) error_exit("cg_user_data_read");
01674 print_indent (indent);
01675 printf ("checking user data \"%s\"\n", name);
01676 fflush (stdout);
01677 go_relative ("UserDefinedData_t", nu, NULL);
01678 #if CGNS_VERSION >= 2400
01679 hasf = cg_famname_read (name);
01680 if (hasf && hasf != CG_NODE_NOT_FOUND)
01681 error_exit("cg_famname_read");
01682 haso = read_ordinal (&ordinal);
01683 if (haso && haso != CG_NODE_NOT_FOUND)
01684 error_exit("cg_ordinal_read");
01685 hasl = read_gridlocation (&location);
01686 if (hasl && hasl != CG_NODE_NOT_FOUND)
01687 error_exit("cg_gridlocation_read");
01688
01689 if (cgnszone == 0)
01690 hasp = CG_NODE_NOT_FOUND;
01691 else {
01692 hasp = cg_ptset_info (&ptype, &npnts);
01693 if (hasp && hasp != CG_NODE_NOT_FOUND)
01694 error_exit("cg_ptset_info");
01695 }
01696 if (verbose) {
01697 if (hasf == CG_OK) {
01698 print_indent (indent+2);
01699 printf ("Family Name=\"%s\"\n", name);
01700 }
01701 if (haso == CG_OK) {
01702 print_indent (indent+2);
01703 printf ("Ordinal=%d\n", ordinal);
01704 }
01705 if (hasl == CG_OK) {
01706 print_indent (indent+2);
01707 printf ("Grid Location=%s\n", cg_GridLocationName(location));
01708 }
01709 if (hasp == CG_OK) {
01710 print_indent (indent+2);
01711 printf ("Point Set Type=%s\n", cg_PointSetTypeName(ptype));
01712 print_indent (indent+2);
01713 printf ("Number Points=%d\n", npnts);
01714 }
01715 }
01716 if (hasf == CG_OK) {
01717 for (n = 0; n < NumFamily; n++) {
01718 if (0 == strcmp (name, Family[n])) break;
01719 }
01720 if (n == NumFamily)
01721 warning (1, "family name \"%s\" not found", name);
01722 }
01723 #endif
01724 if (verbose > 1) {
01725 if (cg_ndescriptors (&nd)) error_exit ("cg_ndescriptors");
01726 for (n = 1; n <= nd; n++) {
01727 if (cg_descriptor_read (n, name, &desc))
01728 error_exit("cg_descriptor_read");
01729 if (desc != NULL) {
01730 print_indent (indent + 2);
01731 printf ("Descriptor %s:\n%s\n", name, desc);
01732 cg_free (desc);
01733 }
01734 }
01735 }
01736
01737 dataclass = read_dataclass ();
01738 punits = read_units (units);
01739 if (verbose) {
01740 if (dataclass >= 0) print_dataclass (dataclass, indent + 2);
01741 if (punits) print_units (punits, indent + 2);
01742 }
01743 if (dataclass < 0) dataclass = parclass;
01744 if (!punits) punits = parunits;
01745
01746 if (cg_narrays (&na)) error_exit ("cg_narrays");
01747 for (n = 1; n <= na; n++) {
01748 if (cg_array_info (n, name, &datatype, &ndim, dims))
01749 error_exit ("cg_array_info");
01750 print_indent (indent + 2);
01751 printf ("checking quantity \"%s\"\n", name);
01752 fflush (stdout);
01753 check_quantity (n, name, dataclass, punits, 0, indent+4);
01754 }
01755
01756 #if CGNS_VERSION >= 2400
01757 check_user_data (dataclass, punits, indent + 2);
01758 #endif
01759 go_relative ("..", 1, NULL);
01760 }
01761 }
01762
01763
01764
01765 static void check_integral (int parclass, int *parunits, int indent)
01766 {
01767 char *desc, name[33];
01768 int n, ni, nint, na, nd, ndim, dims[12];
01769 int dataclass, *punits, units[9];
01770 DataType_t datatype;
01771
01772 if (cg_nintegrals (&nint)) error_exit ("cg_nintegrals");
01773 if (nint <= 0) return;
01774 print_indent (indent);
01775 puts ("checking integral data");
01776 fflush (stdout);
01777
01778 for (ni = 1; ni <= nint; ni++) {
01779 if (cg_integral_read (ni, name)) error_exit("cg_integral_read");
01780 go_relative ("IntegralData_t", ni, NULL);
01781 if (verbose) {
01782 print_indent (indent + 2);
01783 printf ("integral data \"%s\"\n", name);
01784 if (verbose > 1) {
01785 if (cg_ndescriptors (&nd)) error_exit ("cg_ndescriptors");
01786 for (n = 1; n <= nd; n++) {
01787 if (cg_descriptor_read (n, name, &desc))
01788 error_exit("cg_descriptor_read");
01789 if (desc != NULL) {
01790 print_indent (indent + 4);
01791 printf ("Descriptor %s:\n%s\n", name, desc);
01792 cg_free (desc);
01793 }
01794 }
01795 }
01796 }
01797
01798 dataclass = read_dataclass ();
01799 punits = read_units (units);
01800 if (verbose) {
01801 if (dataclass >= 0) print_dataclass (dataclass, indent + 4);
01802 if (punits) print_units (punits, indent + 4);
01803 }
01804 if (dataclass < 0) dataclass = parclass;
01805 if (!punits) punits = parunits;
01806
01807 if (cg_narrays (&na)) error_exit ("cg_narrays");
01808 for (n = 1; n <= na; n++) {
01809 if (cg_array_info (n, name, &datatype, &ndim, dims))
01810 error_exit ("cg_array_info");
01811 print_indent (indent + 4);
01812 printf ("checking quantity \"%s\"\n", name);
01813 fflush (stdout);
01814 if (ndim != 1 || dims[0] != 1)
01815 error ("dimension is not 1");
01816 check_quantity (n, name, dataclass, punits, 0, indent+6);
01817 }
01818
01819 check_user_data (dataclass, punits, indent + 4);
01820 go_relative ("..", 1, NULL);
01821 }
01822 }
01823
01824
01825
01826 static void check_rotating (float *point, float *vector,
01827 int parclass, int *parunits, int indent)
01828 {
01829 char *desc, name[33];
01830 int n, na, nd, ndim, dims[12];
01831 int dataclass, *punits, units[9];
01832 DataType_t datatype;
01833
01834 go_relative ("RotatingCoordinates_t", 1, NULL);
01835
01836 if (verbose) {
01837 print_indent (indent);
01838 printf ("Center=[%g", point[0]);
01839 for (nd = 1; nd < PhyDim; nd++)
01840 printf (",%g", point[nd]);
01841 puts ("]");
01842 print_indent (indent);
01843 printf ("Rate Vector=[%g", vector[0]);
01844 for (nd = 1; nd < PhyDim; nd++)
01845 printf (",%g", vector[nd]);
01846 puts ("]");
01847 }
01848
01849 if (verbose > 1) {
01850 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
01851 for (n = 1; n <= nd; n++) {
01852 if (cg_descriptor_read (n, name, &desc))
01853 error_exit("cg_descriptor_read");
01854 if (desc != NULL) {
01855 print_indent (indent);
01856 printf ("Descriptor %s:\n%s\n", name, desc);
01857 cg_free (desc);
01858 }
01859 }
01860 }
01861
01862 dataclass = read_dataclass ();
01863 punits = read_units (units);
01864 if (verbose) {
01865 if (dataclass >= 0) print_dataclass (dataclass, indent);
01866 if (punits) print_units (punits, indent);
01867 }
01868 if (dataclass < 0) dataclass = parclass;
01869 if (!punits) punits = parunits;
01870
01871 if (cg_narrays (&na)) error_exit("cg_narrays");
01872 for (n = 1; n <= na; n++) {
01873 if (cg_array_info (n, name, &datatype, &ndim, dims))
01874 error_exit("cg_array_info");
01875 print_indent (indent);
01876 printf ("checking rotating data \"%s\"\n", name);
01877 fflush (stdout);
01878 if (strcmp (name, "RotationCenter") &&
01879 strcmp (name, "RotationRateVector"))
01880 warning (1, "not valid as child of RotatingCoordinates");
01881 else
01882 check_quantity (n, name, dataclass, punits, 1, indent + 4);
01883 }
01884
01885 check_user_data (dataclass, punits, indent + 2);
01886
01887 go_relative ("..", 1, NULL);
01888 }
01889
01890
01891
01892 static void check_convergence (int niter, char *NormDefs,
01893 int parclass, int *parunits, int indent)
01894 {
01895 char name[33];
01896 int n, na, ndim, dims[12];
01897 int dataclass, *punits, units[9];
01898 DataType_t datatype;
01899
01900 if (verbose) {
01901 print_indent (indent);
01902 printf ("Number Iterations=%d\n", niter);
01903 if (NormDefs != NULL) {
01904 print_indent (indent);
01905 printf ("Norm Definitions=%s\n", NormDefs);
01906 }
01907 }
01908 if (niter < 1)
01909 warning (2, "number of iterations is not > 0");
01910
01911 if (verbose > 1) {
01912 int nd;
01913 char *desc;
01914 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
01915 for (n = 1; n <= nd; n++) {
01916 if (cg_descriptor_read (n, name, &desc))
01917 error_exit("cg_descriptor_read");
01918 if (desc != NULL && strcmp (name, "NormDefinitions")) {
01919 print_indent (indent);
01920 printf ("Descriptor %s:\n%s\n", name, desc);
01921 }
01922 if (desc != NULL) cg_free (desc);
01923 }
01924 }
01925
01926 dataclass = read_dataclass ();
01927 punits = read_units (units);
01928 if (verbose) {
01929 if (dataclass >= 0) print_dataclass (dataclass, indent);
01930 if (punits) print_units (punits, indent);
01931 }
01932 if (dataclass < 0) dataclass = parclass;
01933 if (!punits) punits = parunits;
01934
01935 if (cg_narrays (&na)) error_exit("cg_narrays");
01936 for (n = 1; n <= na; n++) {
01937 if (cg_array_info (n, name, &datatype, &ndim, dims))
01938 error_exit("cg_array_info");
01939 print_indent (indent);
01940 printf ("checking convergence data \"%s\"\n", name);
01941 fflush (stdout);
01942 if (ndim != 1 || dims[0] != niter)
01943 error ("length of array is not the number of iterations");
01944 if (0 == strncmp (name, "RSD", 3) ||
01945 0 == strncmp (name, "CHG", 3))
01946 check_quantity (n, NULL, dataclass, punits, -1, indent + 2);
01947 else
01948 check_quantity (n, name, dataclass, punits, 1, indent + 2);
01949 }
01950
01951 check_user_data (dataclass, punits, indent);
01952 }
01953
01954
01955
01956 static void check_equation_set (int *flags, int parclass, int *parunits,
01957 int indent)
01958 {
01959 char *desc, name[33];
01960 int n, nd, dataclass, ierr, *punits, units[9], ndiff, diff[6];
01961 GoverningEquationsType_t governing;
01962 ModelType_t model;
01963 int thermrelax, chemkin;
01964 #if CGNS_VERSION >= 2400
01965 int emelec, emmagn, emcond;
01966 #endif
01967
01968 ierr = cg_equationset_chemistry_read (&thermrelax, &chemkin);
01969 if (ierr) {
01970 if (ierr != CG_NODE_NOT_FOUND)
01971 error_exit("cg_equationset_chemistry_read");
01972 thermrelax = chemkin = 0;
01973 }
01974 #if CGNS_VERSION >= 2400
01975 ierr = cg_equationset_elecmagn_read (&emelec, &emmagn, &emcond);
01976 if (ierr) {
01977 if (ierr != CG_NODE_NOT_FOUND);
01978 error_exit("cg_equationset_elecmagn_read");
01979 emelec = emmagn = emcond = 0;
01980 }
01981 #endif
01982
01983 go_relative ("FlowEquationSet_t", 1, NULL);
01984
01985 if (verbose > 1) {
01986 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
01987 for (n = 1; n <= nd; n++) {
01988 if (cg_descriptor_read (n, name, &desc))
01989 error_exit("cg_descriptor_read");
01990 if (desc != NULL) {
01991 print_indent (indent);
01992 printf ("Descriptor %s:\n%s\n", name, desc);
01993 cg_free (desc);
01994 }
01995 }
01996 }
01997
01998 if (LibraryVersion < 2000) {
01999 dataclass = -1;
02000 punits = NULL;
02001 }
02002 else {
02003 dataclass = read_dataclass ();
02004 punits = read_units (units);
02005 }
02006 if (verbose) {
02007 if (dataclass >= 0) print_dataclass (dataclass, indent);
02008 if (punits) print_units (punits, indent);
02009 print_indent (indent);
02010 printf ("Equation Dimension=%d\n", flags[0]);
02011 }
02012 if (dataclass < 0) dataclass = parclass;
02013 if (!punits) punits = parunits;
02014 ndiff = (CellDim * (CellDim + 1)) / 2;
02015
02016 if (flags[0] < 1)
02017 error ("equation dimension < 1");
02018
02019
02020
02021 if (flags[1]) {
02022 if (cg_governing_read (&governing))
02023 error_exit("cg_governing_read");
02024 go_relative ("GoverningEquations_t", 1, NULL);
02025 print_indent (indent);
02026 printf ("Governing Equation=%s\n",
02027 cg_GoverningEquationsTypeName(governing));
02028 if (LibraryVersion < 2200 && goDepth == 2) {
02029 warning (3, "can't get Diffusion Model for FlowEquations"
02030 " under CGNSBase_t\n due to a bug in the CGNS"
02031 " library for versions prior to 2.2");
02032 }
02033 else {
02034 ierr = cg_diffusion_read (diff);
02035 if (ierr && ierr != CG_NODE_NOT_FOUND)
02036 error_exit("cg_diffusion_read");
02037 if (ierr == CG_OK) {
02038 if (verbose) {
02039 print_indent (indent + 2);
02040 printf ("Diffusion Model=[%d", diff[0]);
02041 for (n = 1; n < ndiff; n++)
02042 printf (",%d", diff[n]);
02043 puts ("]");
02044 }
02045 for (n = 0; n < ndiff; n++) {
02046 if (diff[n] < 0 || diff[n] > 1) break;
02047 }
02048 if (n < ndiff)
02049 warning (1, "diffusion model terms not 0 or 1");
02050 }
02051 }
02052 check_user_data (dataclass, punits, indent + 2);
02053 go_relative ("..", 1, NULL);
02054 }
02055
02056
02057
02058 if (flags[2]) {
02059 if (cg_model_read ("GasModel_t", &model))
02060 error_exit("cg_model_read");
02061 print_indent (indent);
02062 printf ("Gas Model=%s\n", cg_ModelTypeName(model));
02063 go_relative ("GasModel_t", 1, NULL);
02064 check_arrays (dataclass, punits, 1, 0, indent + 2);
02065 check_user_data (dataclass, punits, indent + 2);
02066 go_relative ("..", 1, NULL);
02067 }
02068
02069
02070
02071 if (flags[3]) {
02072 if (cg_model_read ("ViscosityModel_t", &model))
02073 error_exit("cg_model_read");
02074 print_indent (indent);
02075 printf ("Viscosity Model=%s\n", cg_ModelTypeName(model));
02076 go_relative ("ViscosityModel_t", 1, NULL);
02077 check_arrays (dataclass, punits, 1, 0, indent + 2);
02078 check_user_data (dataclass, punits, indent + 2);
02079 go_relative ("..", 1, NULL);
02080 }
02081
02082
02083
02084 if (flags[4]) {
02085 if (cg_model_read ("ThermalConductivityModel_t", &model))
02086 error_exit("cg_model_read");
02087 print_indent (indent);
02088 printf ("Thermal Conductivity Model=%s\n",
02089 cg_ModelTypeName(model));
02090 go_relative ("ThermalConductivityModel_t", 1, NULL);
02091 check_arrays (dataclass, punits, 1, 0, indent + 2);
02092 check_user_data (dataclass, punits, indent + 2);
02093 go_relative ("..", 1, NULL);
02094 }
02095
02096
02097
02098 if (flags[5]) {
02099 if (cg_model_read ("TurbulenceClosure_t", &model))
02100 error_exit("cg_model_read");
02101 print_indent (indent);
02102 printf ("Turbulence Closure=%s\n", cg_ModelTypeName(model));
02103 go_relative ("TurbulenceClosure_t", 1, NULL);
02104 check_arrays (dataclass, punits, 1, 0, indent + 2);
02105 check_user_data (dataclass, punits, indent + 2);
02106 go_relative ("..", 1, NULL);
02107 }
02108
02109
02110
02111 if (flags[6]) {
02112 if (cg_model_read ("TurbulenceModel_t", &model))
02113 error_exit("cg_model_read");
02114 go_relative ("TurbulenceModel_t", 1, NULL);
02115 print_indent (indent);
02116 printf ("Turbulence Model=%s\n", cg_ModelTypeName(model));
02117 if (LibraryVersion < 2200 && goDepth == 2) {
02118 warning (3, "can't get Turbulent Diffusion Model for FlowEquations"
02119 " under CGNSBase_t\n due to a bug in the CGNS library"
02120 " for versions prior to 2.2");
02121 }
02122 else {
02123 ierr = cg_diffusion_read (diff);
02124 if (ierr && ierr != CG_NODE_NOT_FOUND)
02125 error_exit("cg_diffusion_read");
02126 if (ierr == CG_OK) {
02127 if (verbose) {
02128 print_indent (indent + 2);
02129 printf ("Turbulent Diffusion Model=[%d", diff[0]);
02130 for (n = 1; n < ndiff; n++)
02131 printf (",%d", diff[n]);
02132 puts ("]");
02133 }
02134 for (n = 0; n < ndiff; n++) {
02135 if (diff[n] < 0 || diff[n] > 1) break;
02136 }
02137 if (n < ndiff)
02138 warning (1, "turbulent diffusion model terms not 0 or 1");
02139 }
02140 }
02141 check_arrays (dataclass, punits, 1, 0, indent + 2);
02142 check_user_data (dataclass, punits, indent + 2);
02143 go_relative ("..", 1, NULL);
02144 }
02145
02146
02147
02148 if (thermrelax) {
02149 if (cg_model_read ("ThermalRelaxationModel_t", &model))
02150 error_exit ("cg_model_read");
02151 print_indent (indent);
02152 printf ("Thermal Relaxation Model=%s\n", cg_ModelTypeName(model));
02153 go_relative ("ThermalRelaxationModel_t", 1, NULL);
02154 check_arrays (dataclass, punits, 1, 0, indent + 2);
02155 check_user_data (dataclass, punits, indent + 2);
02156 go_relative ("..", 1, NULL);
02157 }
02158
02159
02160
02161
02162 if (chemkin) {
02163 if (cg_model_read ("ChemicalKineticsModel_t", &model))
02164 error_exit ("cg_model_read");
02165 print_indent (indent);
02166 printf ("Chemical Kinetics Model=%s\n", cg_ModelTypeName(model));
02167 go_relative ("ChemicalKineticsModel_t", 1, NULL);
02168 check_arrays (dataclass, punits, 1, 0, indent + 2);
02169 check_user_data (dataclass, punits, indent + 2);
02170 go_relative ("..", 1, NULL);
02171 }
02172
02173 #if CGNS_VERSION >= 2400
02174
02175
02176
02177 if (emelec) {
02178 if (cg_model_read ("EMElectricFieldModel_t", &model))
02179 error_exit ("cg_model_read");
02180 print_indent (indent);
02181 printf ("EM Electric Field Model=%s\n", cg_ModelTypeName(model));
02182 go_relative ("EMElectricFieldModel_t", 1, NULL);
02183 check_arrays (dataclass, punits, 1, 0, indent + 2);
02184 check_user_data (dataclass, punits, indent + 2);
02185 go_relative ("..", 1, NULL);
02186 }
02187
02188
02189
02190 if (emmagn) {
02191 if (cg_model_read ("EMMagneticFieldModel_t", &model))
02192 error_exit ("cg_model_read");
02193 print_indent (indent);
02194 printf ("EM Magnetic Field Model=%s\n", cg_ModelTypeName(model));
02195 go_relative ("EMMagneticFieldModel_t", 1, NULL);
02196 check_arrays (dataclass, punits, 1, 0, indent + 2);
02197 check_user_data (dataclass, punits, indent + 2);
02198 go_relative ("..", 1, NULL);
02199 }
02200
02201
02202
02203 if (emcond) {
02204 if (cg_model_read ("EMConductivityModel_t", &model))
02205 error_exit ("cg_model_read");
02206 print_indent (indent);
02207 printf ("EM Conductivity Model=%s\n", cg_ModelTypeName(model));
02208 go_relative ("EMConductivityModel_t", 1, NULL);
02209 check_arrays (dataclass, punits, 1, 0, indent + 2);
02210 check_user_data (dataclass, punits, indent + 2);
02211 go_relative ("..", 1, NULL);
02212 }
02213
02214 #endif
02215
02216 go_relative ("..", 1, NULL);
02217 }
02218
02219
02220
02221 static void check_coordinates (int ng)
02222 {
02223 char name[33];
02224 int ierr, n, np, rind[6], rmin[3], rmax[3];
02225 int nc, ncoords, mask, coordset[4];
02226 int *punits, units[9], dataclass;
02227 float *coord, cmin, cmax;
02228 DataType_t datatype;
02229 ZONE *z = &Zones[cgnszone-1];
02230
02231 if (cg_grid_read (cgnsfn, cgnsbase, cgnszone, ng, name))
02232 error_exit("cg_grid_read");
02233 strcpy (GridCoordinate[ng-1], name);
02234 printf (" checking coordinates \"%s\"\n", name);
02235 fflush (stdout);
02236
02237 go_absolute ("Zone_t", cgnszone, "GridCoordinates_t", ng, NULL);
02238
02239 if (verbose > 1) {
02240 int nd;
02241 char *desc;
02242 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
02243 for (n = 1; n <= nd; n++) {
02244 if (cg_descriptor_read (n, name, &desc))
02245 error_exit("cg_descriptor_read");
02246 if (desc != NULL) {
02247 printf (" Descriptor %s:\n%s\n", name, desc);
02248 cg_free (desc);
02249 }
02250 }
02251 }
02252
02253 dataclass = read_dataclass ();
02254 punits = read_units (units);
02255 if (verbose) {
02256 if (dataclass >= 0) print_dataclass (dataclass, 4);
02257 if (punits) print_units (punits, 4);
02258 }
02259 if (dataclass < 0) dataclass = z->dataclass;
02260 if (!punits) punits = z->punits;
02261
02262 ierr = read_rind (rind);
02263 if (ierr) {
02264 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_rind_read");
02265 for (n = 0; n < 6; n++)
02266 rind[n] = 0;
02267 }
02268 else {
02269 if (verbose) {
02270 printf (" Rind=[%d", rind[0]);
02271 for (n = 1; n < 2 * z->idim; n++)
02272 printf (",%d", rind[n]);
02273 puts ("]");
02274 }
02275 if (z->type == Unstructured && FileVersion < 2400)
02276 error ("rind not valid for unstructured zones");
02277 }
02278
02279 for (n = 0, np = 1; n < z->idim; n++) {
02280 rmin[n] = 1;
02281 rmax[n] = z->dims[0][n] + rind[2*n] + rind[2*n+1];
02282 np *= rmax[n];
02283 }
02284 if (NULL == (coord = (float *) malloc (np * sizeof(float)))) {
02285 fprintf (stderr, "malloc failed for %d coordinate values\n", np);
02286 exit (1);
02287 }
02288 if (z->maxnode < np) z->maxnode = np;
02289
02290 if (cg_ncoords (cgnsfn, cgnsbase, cgnszone, &ncoords))
02291 error_exit("cg_ncoords");
02292 if (ncoords < PhyDim)
02293 error ("number coordinates < physical dimensions");
02294 for (n = 0; n < 4; n++)
02295 coordset[n] = 0;
02296
02297 for (nc = 1; nc <= ncoords; nc++) {
02298 if (cg_coord_info (cgnsfn, cgnsbase, cgnszone, nc, &datatype, name))
02299 error_exit("cg_coord_info");
02300 if (cg_coord_read (cgnsfn, cgnsbase, cgnszone, name, RealSingle,
02301 rmin, rmax, coord))
02302 error_exit("cg_coord_read");
02303 printf (" checking coordinate \"%s\"\n", name);
02304 fflush (stdout);
02305 cmin = cmax = coord[0];
02306 for (n = 1; n < np; n++) {
02307 if (cmin > coord[n]) cmin = coord[n];
02308 if (cmax < coord[n]) cmax = coord[n];
02309 }
02310 if (verbose)
02311 printf(" Coordinate Range=%g -> %g (%g)\n",
02312 cmin, cmax, cmax-cmin);
02313 if (cmin == cmax)
02314 warning(1, "coordinate range is 0");
02315 if (0 == strcmp (name, "CoordinateX"))
02316 coordset[0] |= 1;
02317 else if (0 == strcmp (name, "CoordinateY"))
02318 coordset[0] |= 2;
02319 else if (0 == strcmp (name, "CoordinateZ")) {
02320 coordset[0] |= 4;
02321 coordset[1] |= 4;
02322 }
02323 else if (0 == strcmp (name, "CoordinateR"))
02324 coordset[1] |= 1;
02325 else if (0 == strcmp (name, "CoordinateTheta")) {
02326 coordset[1] |= 2;
02327 coordset[2] |= 2;
02328 }
02329 else if (0 == strcmp (name, "CoordinatePhi"))
02330 coordset[2] |= 4;
02331 else if (0 == strcmp (name, "CoordinateXi"))
02332 coordset[3] |= 1;
02333 else if (0 == strcmp (name, "CoordinateEta"))
02334 coordset[3] |= 2;
02335 else if (0 == strcmp (name, "CoordinateZeta"))
02336 coordset[3] |= 4;
02337 check_quantity (nc, name, dataclass, punits, 1, 6);
02338 }
02339 free (coord);
02340
02341 for (mask = 0, n = 0; n < PhyDim; n++)
02342 mask |= (1 << n);
02343 for (n = 0; n < 4; n++) {
02344 if ((coordset[n] & mask) == mask) break;
02345 }
02346 if (n == 4)
02347 error ("a complete coordinate system was not found");
02348 }
02349
02350
02351
02352 static void check_elements (void)
02353 {
02354 int i, j, n, nn, ns, nelem, ne, *pe;
02355 int type, is, nf, np, nint, next;
02356 ELEMSET *es;
02357 FACE *face, *pf;
02358 ZONE *z = &Zones[cgnszone-1];
02359
02360 puts (" checking elements");
02361 if (verbose) {
02362 printf (" Number Element Sets=%d\n", z->nsets);
02363 printf (" [0D,1D,2D,3D] Elements=[%d,%d,%d,%d]\n",
02364 z->nn, z->ne, z->ns, z->nv);
02365 if (z->faces)
02366 printf (" Number Volume Faces=%d\n", HashSize(z->faces));
02367 }
02368 fflush (stdout);
02369
02370 nelem = CellDim == 2 ? z->ns : z->nv;
02371 if (nelem < z->dims[1][0])
02372 error ("number %dD elements < specified in zone dimensions", CellDim);
02373 if (nelem > z->dims[1][0])
02374 warning (1, "number %dD elements > specified in zone dimensions",
02375 CellDim);
02376 if (CellDim == 3 && z->nv == 0)
02377 error ("no 3D elements exist and CellDim is 3");
02378 if (CellDim == 2) {
02379 if (z->nv)
02380 error ("3D elements exist and CellDim is 2");
02381 if (z->ns == 0)
02382 error ("no 2D elements exist and CellDim is 2");
02383 }
02384
02385 is = z->sets->is;
02386 if (is != 1)
02387 warning (1, "element numbering does not start at 1");
02388
02389
02390
02391 for (es = z->sets, ns = 0; ns < z->nsets; ns++, es++) {
02392 printf (" checking element set \"%s\"\n", es->name);
02393 if (verbose) {
02394 printf (" Element Set Type=%s\n",
02395 cg_ElementTypeName(es->type));
02396 printf (" Element Range=[%d,%d]\n", es->is, es->ie);
02397 if (es->rind[0] || es->rind[1])
02398 printf (" Rind Elements=[%d,%d]\n",
02399 es->rind[0], es->rind[1]);
02400 printf (" [0D,1D,2D,3D] Elements=[%d,%d,%d,%d]\n",
02401 es->nn, es->ne, es->ns, es->nv);
02402 }
02403 if (ns && z->sets[ns].is != is)
02404 warning (1, "element numbers are not consecutative with \"%s\"",
02405 z->sets[ns-1].name);
02406 is = z->sets[ns].ie + 1;
02407 for (nn = 0; nn < z->nsets; nn++) {
02408 if (nn != ns) {
02409 if ((z->sets[nn].is >= z->sets[ns].is &&
02410 z->sets[nn].is <= z->sets[ns].ie) ||
02411 (z->sets[nn].ie >= z->sets[ns].is &&
02412 z->sets[nn].ie <= z->sets[ns].ie))
02413 error ("element numbers overlap those for \"%s\"",
02414 z->sets[nn].name);
02415 }
02416 }
02417
02418 if (es->invalid < 0) {
02419 if (es->invalid == -1)
02420 printf ("INTERNAL:can't handle %s element set\n",
02421 cg_ElementTypeName(es->type));
02422 else if (es->invalid == -2)
02423 error ("MIXED elements not allowed in a MIXED element set");
02424 else if (es->invalid == -3)
02425 printf("INTERNAL: error with element size in MIXED\n");
02426 else
02427 printf("INTERNAL: error processing element set\n");
02428 continue;
02429 }
02430 if (es->invalid > 0) {
02431 #if CGNS_VERSION >= 3000
02432 if (es->type == NFACE_n) {
02433 error ("%d polyhedra faces are not valid face elements",
02434 es->invalid);
02435 continue;
02436 }
02437 #endif
02438 error ("%d element nodes are out of range", es->invalid);
02439 continue;
02440 }
02441 if (z->faces == NULL || es->ns == 0 || es->type < TRI_3)
02442 continue;
02443 if (es->type > QUAD_9 && es->type != MIXED) {
02444 #if CGNS_VERSION >= 3000
02445 if (es->type != NGON_n)
02446 #endif
02447 continue;
02448 }
02449
02450 nelem = es->ie - es->is + 1 - es->rind[1];
02451 type = es->type;
02452 pe = es->elements;
02453 nf = np = nint = next = 0;
02454 for (ne = 0; ne < nelem; ne++) {
02455 if (es->type == MIXED) {
02456 type = (ElementType_t)*pe++;
02457 if (type >= NGON_n) {
02458 nn = (int)(type - NGON_n);
02459 type = NGON_n;
02460 }
02461 else {
02462 cg_npe (type, &nn);
02463 }
02464 }
02465 #if CGNS_VERSION >= 3000
02466 else if (es->type == NGON_n) {
02467 nn = *pe++;
02468 }
02469 #endif
02470 else {
02471 cg_npe (type, &nn);
02472 }
02473 if (ne >= es->rind[0] && nn >= 3 && (type == NGON_n ||
02474 (type >= TRI_3 && type <= QUAD_9))) {
02475 #ifndef USE_MID_NODES
02476 if (type == QUAD_9)
02477 face = new_face (8, pe);
02478 else
02479 #endif
02480 face = new_face (nn, pe);
02481 pf = (FACE *) HashFind (z->faces, face);
02482 free (face);
02483 if (pf == NULL)
02484 nf++;
02485 else {
02486 if (pf->e2)
02487 nint++;
02488 else
02489 next++;
02490 if (es->parent) {
02491 n = ne + nelem;
02492 i = n + nelem;
02493 j = i + nelem;
02494 if (es->parent[ne] == pf->e1) {
02495 if (es->parent[i] != pf->f1 ||
02496 es->parent[n] != pf->e2 ||
02497 es->parent[j] != pf->f2) np++;
02498 }
02499 else if (es->parent[ne] == pf->e2) {
02500 if (es->parent[i] != pf->f2 ||
02501 es->parent[n] != pf->e1 ||
02502 es->parent[j] != pf->f1) np++;
02503 }
02504 else
02505 np++;
02506 }
02507 }
02508 }
02509 pe += nn;
02510 }
02511
02512 if (verbose)
02513 printf (" [internal,external] Faces=[%d,%d]\n", nint, next);
02514 if (nf)
02515 warning (1, "%d faces are not faces of the volume elements", nf);
02516 if (np)
02517 error ("%d faces have invalid parent data", np);
02518 if (es->parent) {
02519 free (es->parent);
02520 es->parent = NULL;
02521 }
02522 }
02523 }
02524
02525
02526
02527 static void check_struct_interface (ZONE *z, PointSetType_t ptype,
02528 int npts, int *pts, int bndry)
02529 {
02530 int n, id, np, n1, n2, n3, nerr1, nerr2;
02531
02532 nerr1 = nerr2 = 0;
02533
02534
02535
02536 if (ptype == PointList) {
02537 for (n = 0, np = 0; np < npts; np++) {
02538 n1 = n2 = 0;
02539 for (id = 0; id < z->idim; id++) {
02540 if (pts[n] < 1 || pts[n] > z->dims[0][id])
02541 n1++;
02542 else if (pts[n] == 1 || pts[n] == z->dims[0][id])
02543 n2++;
02544 n++;
02545 }
02546 if (n1) nerr1++;
02547 if (!n2) nerr2++;
02548 }
02549 if (nerr1)
02550 error ("%d points are out of range", nerr1);
02551 if (nerr2 && bndry)
02552 warning (2, "%d points are not boundary points", nerr2);
02553 return;
02554 }
02555
02556
02557
02558 if (bndry) {
02559 for (n = 0, np = 0; np < npts; np++) {
02560 n1 = n2 = n3 = 0;
02561 for (id = 0; id < z->idim; id++) {
02562 if (pts[n] < 1 || pts[n] > z->dims[0][id])
02563 n1++;
02564 else if (pts[n] == 1)
02565 n2++;
02566 else if (pts[n] == z->dims[0][id])
02567 n3++;
02568 n++;
02569 }
02570 if (n1 || n3 > 1) nerr1++;
02571 if (!n2 && !n3) nerr2++;
02572 }
02573 }
02574
02575
02576
02577 else {
02578 for (n = 0, np = 0; np < npts; np++) {
02579 n1 = 0;
02580 for (id = 0; id < z->idim; id++) {
02581 if (pts[n+id] < 1 || pts[n+id] >= z->dims[0][id])
02582 n1++;
02583 n++;
02584 }
02585 if (n1) nerr1++;
02586 }
02587 }
02588
02589 if (nerr1)
02590 error ("%d elements are out of range", nerr1);
02591 if (nerr2)
02592 warning (2, "%d elements are not boundary elements", nerr2);
02593 }
02594
02595
02596
02597 static void check_unstruct_interface (ZONE *z, PointSetType_t ptype,
02598 int npts, int *pts, int bndry)
02599 {
02600 int dim, n, nn, id, nerr1, nerr2, nerr3, *nodes;
02601 FACE *face, *pf;
02602
02603 nerr1 = nerr2 = nerr3 = 0;
02604
02605
02606
02607 if (ptype == PointList) {
02608 for (n = 0; n < npts; n++) {
02609 if (pts[n] < 1 || pts[n] > z->nnodes) nerr1++;
02610 }
02611 if (nerr1)
02612 error ("%d node numbers are out of range", nerr1);
02613 if (z->nextnodes && bndry) {
02614 for (n = 0; n < npts; n++) {
02615 if (!find_extnode (z, pts[n])) nerr2++;
02616 }
02617 if (nerr2)
02618 warning (2, "%d nodes are not boundary nodes", nerr2);
02619 }
02620 return;
02621 }
02622
02623
02624
02625 dim = bndry ? CellDim - 1 : CellDim;
02626
02627 for (n = 0; n < npts; n++) {
02628 nodes = find_element (z, pts[n], &id, &nn);
02629 if (nodes == NULL)
02630 nerr1++;
02631 else {
02632 if (id != dim) nerr2++;
02633 if (z->faces != NULL && id == 2 && nn > 2) {
02634 face = new_face (nn, nodes);
02635 pf = (FACE *) HashFind (z->faces, face);
02636 if (pf == NULL || pf->e2) nerr3++;
02637 free (face);
02638 }
02639 }
02640 }
02641 if (nerr1)
02642 error ("%d element numbers are out of range", nerr1);
02643 if (nerr2)
02644 warning (1, "%d elements have invalid dimension", nerr2);
02645 if (nerr3 && bndry)
02646 warning (2, "%d elements are not boundary elements", nerr3);
02647 }
02648
02649
02650
02651 static int check_interface (ZONE *z, PointSetType_t ptype,
02652 GridLocation_t location, int npts, int *pts, int bndry)
02653 {
02654 int np, *p;
02655
02656 if (ptype == PointListDonor) ptype = PointList;
02657 if (ptype == CellListDonor) ptype = ElementList;
02658 if (ptype != PointRange && ptype != PointList &&
02659 ptype != ElementRange && ptype != ElementList) {
02660 error ("invalid point type");
02661 return 0;
02662 }
02663 if (location < Vertex || location >= EdgeCenter) {
02664 error ("invalid grid location");
02665 return 0;
02666 }
02667 if (z->idim < 1 || z->idim > 3) {
02668 warning (1, "can't evaluate since zone \"%s\" in invalid", z->name);
02669 return 0;
02670 }
02671
02672 if (ptype == PointRange && location != Vertex) ptype = ElementRange;
02673 if (ptype == PointList && location != Vertex) ptype = ElementList;
02674
02675 if (ptype == PointRange || ptype == ElementRange) {
02676 int n, i, j, k;
02677 int pmin[3], pmax[3];
02678 for (np = 1, n = 0; n < z->idim; n++) {
02679 if (pts[n] < pts[n+z->idim]) {
02680 pmin[n] = pts[n];
02681 pmax[n] = pts[n+z->idim];
02682 }
02683 else {
02684 pmin[n] = pts[n+z->idim];
02685 pmax[n] = pts[n];
02686 }
02687 np *= (pmax[n] - pmin[n] + 1);
02688 }
02689 p = (int *) malloc (np * z->idim * sizeof(int));
02690 if (p == NULL) {
02691 fprintf (stderr, "malloc failed for point/element list\n");
02692 exit (1);
02693 }
02694 n = 0;
02695 if (z->idim == 1) {
02696 for (i = pmin[0]; i <= pmax[0]; i++)
02697 p[n++] = i;
02698 }
02699 else if (z->idim == 2) {
02700 for (i = pmin[0]; i <= pmax[0]; i++) {
02701 for (j = pmin[1]; j <= pmax[1]; j++) {
02702 p[n++] = i;
02703 p[n++] = j;
02704 }
02705 }
02706 }
02707 else {
02708 for (i = pmin[0]; i <= pmax[0]; i++) {
02709 for (j = pmin[1]; j <= pmax[1]; j++) {
02710 for (k = pmin[2]; k <= pmax[2]; k++) {
02711 p[n++] = i;
02712 p[n++] = j;
02713 p[n++] = k;
02714 }
02715 }
02716 }
02717 }
02718 if (ptype == PointRange)
02719 ptype = PointList;
02720 else
02721 ptype = ElementList;
02722 }
02723 else {
02724 np = npts;
02725 p = pts;
02726 }
02727
02728 if (z->type == Structured)
02729 check_struct_interface (z, ptype, np, p, bndry);
02730 else
02731 check_unstruct_interface (z, ptype, np, p, bndry);
02732
02733 if (p != pts) free (p);
02734 return np;
02735 }
02736
02737
02738
02739 static GridLocation_t check_location (ZONE *z, PointSetType_t ptype,
02740 GridLocation_t location)
02741 {
02742 switch (location) {
02743 case Vertex:
02744 if (ptype == ElementRange || ptype == ElementList)
02745 warning (1, "should not use Vertex with ElementList"
02746 " or ElementRange");
02747 break;
02748 case FaceCenter:
02749 if (z->type == Structured)
02750 warning (2,
02751 "use [IJK]FaceCenter with Structured grids");
02752 break;
02753 case IFaceCenter:
02754 if (z->type != Structured) {
02755 error ("IFaceCenter only valid for Structured grids");
02756 return FaceCenter;
02757 }
02758 break;
02759 case JFaceCenter:
02760 if (z->type != Structured || z->idim < 2) {
02761 error ("JFaceCenter only valid for Structured grids"
02762 " with CellDim > 1");
02763 return FaceCenter;
02764 }
02765 break;
02766 case KFaceCenter:
02767 if (z->type != Structured || z->idim < 3) {
02768 error ("KFaceCenter only valid for Structured grids"
02769 " with CellDim > 2");
02770 return FaceCenter;
02771 }
02772 break;
02773 case CellCenter:
02774 if (z->type == Structured && FileVersion >= 2300)
02775 warning (2, "use [IJK]FaceCenter location rather"
02776 " than CellCenter");
02777 else
02778 warning (2, "use FaceCenter location rather than"
02779 " CellCenter");
02780 return FaceCenter;
02781 break;
02782 default:
02783 error ("grid location not Vertex,CellCenter,FaceCenter"
02784 " or [IJK]FaceCenter");
02785 break;
02786 }
02787 if (ptype == ElementRange || ptype == ElementList)
02788 return FaceCenter;
02789 return location;
02790 }
02791
02792
02793
02794 static void check_BCdata (BCType_t bctype, int dirichlet, int neumann,
02795 int size, int parclass, int *parunits, int indent)
02796 {
02797 char name[33], *desc;
02798 int ierr, n, nd;
02799 int *punits, units[9], dataclass;
02800 #if CGNS_VERSION >= 2400
02801 GridLocation_t location;
02802 PointSetType_t ptype;
02803 int hasl, hasp, npnts;
02804
02805 hasl = read_gridlocation (&location);
02806 if (hasl && hasl != CG_NODE_NOT_FOUND)
02807 error_exit("cg_gridlocation_read");
02808
02809 if (cgnszone == 0)
02810 hasp = CG_NODE_NOT_FOUND;
02811 else {
02812 hasp = cg_ptset_info (&ptype, &npnts);
02813 if (hasp && hasp != CG_NODE_NOT_FOUND)
02814 error_exit("cg_ptset_info");
02815 if (hasp == CG_OK && hasl != CG_OK) {
02816 location = Vertex;
02817 hasl = CG_OK;
02818 }
02819 }
02820 #endif
02821
02822 if (verbose) {
02823 print_indent (indent);
02824 printf ("BC Type=%s\n", cg_BCTypeName(bctype));
02825 print_indent (indent);
02826 printf ("Dirichlet Data=%s\n", dirichlet ? "yes" : "no");
02827 print_indent (indent);
02828 printf ("Neumann Data=%s\n", neumann ? "yes" : "no");
02829 #if CGNS_VERSION >= 2400
02830 if (hasl == CG_OK) {
02831 print_indent (indent);
02832 printf ("Grid Location=%s\n", cg_GridLocationName(location));
02833 }
02834 if (hasp == CG_OK) {
02835 print_indent (indent);
02836 printf ("Point Set Type=%s\n", cg_PointSetTypeName(ptype));
02837 print_indent (indent);
02838 printf ("Number Points=%d\n", npnts);
02839 }
02840 #endif
02841 if (verbose > 1) {
02842 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
02843 for (n = 1; n <= nd; n++) {
02844 if (cg_descriptor_read (n, name, &desc))
02845 error_exit("cg_descriptor_read");
02846 if (desc != NULL) {
02847 print_indent (indent);
02848 printf ("Descriptor %s:\n%s\n", name, desc);
02849 cg_free (desc);
02850 }
02851 }
02852 }
02853 }
02854
02855 dataclass = read_dataclass ();
02856 punits = read_units (units);
02857 if (verbose) {
02858 if (dataclass >= 0) print_dataclass (dataclass, indent);
02859 if (punits) print_units (punits, indent);
02860 }
02861 if (dataclass < 0) dataclass = parclass;
02862 if (punits == NULL) punits = parunits;
02863
02864 ierr = cg_state_read (&desc);
02865 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_state_read");
02866 if (ierr == CG_OK) {
02867 print_indent (indent);
02868 puts ("checking reference state");
02869 if (desc != NULL) {
02870 if (verbose > 1) {
02871 print_indent (indent+2);
02872 printf ("Descriptor:%s\n", desc);
02873 }
02874 cg_free (desc);
02875 }
02876 fflush (stdout);
02877 go_relative ("ReferenceState_t", 1, NULL);
02878 check_arrays (dataclass, punits, 1, 0, indent+2);
02879 go_relative ("..", 1, NULL);
02880 }
02881
02882 check_user_data (dataclass, punits, indent);
02883
02884 #if CGNS_VERSION >= 2400
02885 if (hasp == CG_OK) {
02886 int *pts;
02887 ZONE *z = &Zones[cgnszone-1];
02888
02889 print_indent (indent);
02890 puts ("checking BCDataSet interface");
02891 fflush (stdout);
02892 location = check_location (z, ptype, location);
02893 if (npnts < 1) {
02894 error ("number of points for Point Set less than 1");
02895 size = 0;
02896 }
02897 else if (npnts != 2 &&
02898 (ptype == PointRange || ptype == ElementRange)) {
02899 error ("number of points not 2 for Point/Element Range");
02900 size = 0;
02901 }
02902 else {
02903 pts = (int *) malloc (z->idim * npnts * sizeof(int));
02904 if (NULL == pts) {
02905 fprintf (stderr, "malloc failed for BCDataSet points\n");
02906 exit (1);
02907 }
02908 if (cg_ptset_read (pts)) error_exit("cg_ptset_read");
02909 if (ptype == PointRange || ptype == ElementRange) {
02910 for (n = 0; n < z->idim; n++) {
02911 if (pts[n] > pts[n+z->idim]) {
02912 warning (1, "start value > end value for range");
02913 break;
02914 }
02915 }
02916 }
02917 size = check_interface (z, ptype, location, npnts, pts, 1);
02918 free (pts);
02919 }
02920 }
02921 else {
02922 if (hasp == CG_OK)
02923 warning (1, "grid location should be used only with point set");
02924 }
02925 #endif
02926
02927 if (size) size = -size;
02928
02929 if (dirichlet) {
02930 print_indent (indent);
02931 puts ("checking Dirichlet data");
02932 go_relative ("BCData_t", Dirichlet, NULL);
02933 check_arrays (dataclass, punits, 0, size, indent+2);
02934 go_relative ("..", 1, NULL);
02935 }
02936
02937 if (neumann) {
02938 print_indent (indent);
02939 puts ("checking Neumann data");
02940 go_relative ("BCData_t", Neumann, NULL);
02941 check_arrays (dataclass, punits, 0, size, indent+2);
02942 go_relative ("..", 1, NULL);
02943 }
02944 }
02945
02946
02947
02948 static void check_BCdataset (int nb, int nd, int size,
02949 int parclass, int *parunits)
02950 {
02951 char name[33];
02952 int dirichlet, neumann;
02953 BCType_t bctype;
02954
02955 if (cg_dataset_read (cgnsfn, cgnsbase, cgnszone, nb, nd,
02956 name, &bctype, &dirichlet, &neumann))
02957 error_exit("cg_dataset_read");
02958 printf (" checking BC data set \"%s\"\n", name);
02959 fflush (stdout);
02960 go_absolute ("Zone_t", cgnszone, "ZoneBC_t", 1, "BC_t", nb,
02961 "BCDataSet_t", nd, NULL);
02962 check_BCdata (bctype, dirichlet, neumann, size, parclass, parunits, 6);
02963 }
02964
02965
02966
02967 static void check_BC (int nb, int parclass, int *parunits)
02968 {
02969 char name[33], *desc;
02970 int n, nd, ierr, npts, ndataset;
02971 int nrmlindex[3], nrmlflag, *pts;
02972 int *punits, units[9], dataclass;
02973 void *nrmllist;
02974 BCType_t bctype;
02975 PointSetType_t ptype;
02976 DataType_t datatype;
02977 GridLocation_t location;
02978 WallFunctionType_t wtype;
02979 AreaType_t atype;
02980 float area;
02981 ZONE *z = &Zones[cgnszone-1];
02982
02983 if (cg_boco_info (cgnsfn, cgnsbase, cgnszone, nb, name, &bctype,
02984 &ptype, &npts, nrmlindex, &nrmlflag, &datatype, &ndataset))
02985 error_exit("cg_boco_info");
02986 printf (" checking BC \"%s\"\n", name);
02987 if (verbose) {
02988 printf (" BC Type=%s\n", cg_BCTypeName(bctype));
02989 printf (" Point Set Type=%s\n", cg_PointSetTypeName(ptype));
02990 }
02991 fflush (stdout);
02992
02993 go_absolute ("Zone_t", cgnszone, "ZoneBC_t", 1, "BC_t", nb, NULL);
02994
02995 if (FileVersion >= 1270 && FileVersion <= 2200) {
02996 if (ptype != PointRange && ptype != PointList) {
02997 error ("point set type not PointRange or PointList");
02998 return;
02999 }
03000 }
03001 else {
03002 if (ptype != PointRange && ptype != PointList &&
03003 ptype != ElementRange && ptype != ElementList) {
03004 error ("point set type not PointRange, PointList, ElementRange"
03005 " or ElementList");
03006 return;
03007 }
03008 }
03009
03010 if (FileVersion < 1270) {
03011 if (ptype == ElementRange || ptype == ElementList)
03012 location = FaceCenter;
03013 else
03014 location = Vertex;
03015 }
03016 else {
03017 ierr = read_gridlocation (&location);
03018 if (ierr) {
03019 if (ierr != CG_NODE_NOT_FOUND)
03020 error_exit("cg_gridlocation_read");
03021 if (ptype == ElementRange || ptype == ElementList)
03022 location = FaceCenter;
03023 else
03024 location = Vertex;
03025 }
03026 else {
03027 if (verbose)
03028 printf (" Grid Location=%s\n",
03029 cg_GridLocationName(location));
03030 location = check_location (z, ptype, location);
03031 }
03032 }
03033
03034 if (npts < 1) {
03035 error ("number of points is less than 1");
03036 return;
03037 }
03038 if (FileVersion >= 1270 && FileVersion <= 2200) {
03039 if (ptype == PointRange && npts != 2) {
03040 error ("number of points is not 2 for PointRange");
03041 return;
03042 }
03043 }
03044 else {
03045 if ((ptype == PointRange || ptype == ElementRange) && npts != 2) {
03046 error ("number of points is not 2 for PointRange/ElementRange");
03047 return;
03048 }
03049 }
03050 if (z->idim == 0) return;
03051
03052 ierr = check_node ("\"int[IndexDimension]\"");
03053
03054 if (verbose) {
03055 if (ierr == CG_OK) {
03056 printf (" Normal Index=[%d", nrmlindex[0]);
03057 for (n = 1; n < z->idim; n++)
03058 printf (",%d", nrmlindex[n]);
03059 puts ("]");
03060 }
03061 if (nrmlflag) {
03062 puts (" Normals Defined=yes");
03063 printf (" Number Normals=%d\n", nrmlflag / PhyDim);
03064 }
03065 else
03066 puts (" Normals Defined=no");
03067 }
03068 fflush (stdout);
03069
03070 if (ierr == CG_OK && z->type != Structured)
03071 error ("normal index is only valid for Structured grids");
03072 if (nrmlflag) {
03073 if (datatype != RealSingle && datatype != RealDouble) {
03074 error ("normal data type is not RealSingle or RealDouble");
03075 if (LibraryVersion < 2200) return;
03076 }
03077 }
03078
03079 pts = (int *) malloc (z->idim * npts * sizeof(int));
03080 if (NULL == pts) {
03081 fprintf (stderr, "malloc failed for BC points\n");
03082 exit (1);
03083 }
03084 nrmllist = NULL;
03085 if (nrmlflag && LibraryVersion < 2200) {
03086 int n = datatype == RealSingle ? sizeof(float) : sizeof(double);
03087 nrmllist = (void *) malloc (nrmlflag * n);
03088 if (nrmllist == NULL) {
03089 fprintf (stderr, "malloc failed for BC normals\n");
03090 exit (1);
03091 }
03092 }
03093 if (cg_boco_read (cgnsfn, cgnsbase, cgnszone, nb, pts, nrmllist))
03094 error_exit("cg_boco_read");
03095 if (nrmllist) free (nrmllist);
03096
03097 ierr = cg_famname_read (name);
03098 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_famname_read");
03099 if (ierr == CG_NODE_NOT_FOUND) {
03100 if (bctype == FamilySpecified)
03101 warning (1,
03102 "BC Type is FamilySpecified but no family name is given");
03103 }
03104 else {
03105 if (verbose) printf (" Family=\"%s\"\n", name);
03106 for (n = 0; n < NumFamily; n++) {
03107 if (0 == strcmp (name, Family[n])) break;
03108 }
03109 if (n == NumFamily &&
03110 (FileVersion >= 1200 || strcmp(name, "ORPHAN")))
03111 warning (1, "family name \"%s\" not found", name);
03112 }
03113
03114 ierr = read_ordinal (&n);
03115 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_ordinal_read");
03116 if (ierr == CG_OK && verbose)
03117 printf (" Ordinal=%d\n", n);
03118
03119 if (verbose > 1) {
03120 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03121 for (n = 1; n <= nd; n++) {
03122 if (cg_descriptor_read (n, name, &desc))
03123 error_exit("cg_descriptor_read");
03124 if (desc != NULL) {
03125 printf (" Descriptor %s:\n%s\n", name, desc);
03126 cg_free (desc);
03127 }
03128 }
03129 }
03130
03131 dataclass = read_dataclass ();
03132 punits = read_units (units);
03133 if (verbose) {
03134 if (dataclass >= 0) print_dataclass (dataclass, 4);
03135 if (punits) print_units (punits, 4);
03136 }
03137 if (dataclass < 0) dataclass = parclass;
03138 if (punits == NULL) punits = parunits;
03139
03140 ierr = cg_state_read (&desc);
03141 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_state_read");
03142 if (ierr == CG_OK) {
03143 puts (" checking reference state");
03144 if (desc != NULL) {
03145 if (verbose > 1)
03146 printf (" Descriptor:%s\n", desc);
03147 cg_free (desc);
03148 }
03149 fflush (stdout);
03150 go_relative ("ReferenceState_t", 1, NULL);
03151 check_arrays (dataclass, punits, 1, 0, 6);
03152 go_relative ("..", 1, NULL);
03153 }
03154
03155 check_user_data (dataclass, punits, 4);
03156
03157 puts (" checking BC interface");
03158 fflush (stdout);
03159 if (ptype == PointRange || ptype == ElementRange) {
03160 for (n = 0; n < z->idim; n++) {
03161 if (pts[n] > pts[n+z->idim]) {
03162 warning (1, "start value > end value for range");
03163 break;
03164 }
03165 }
03166 }
03167 npts = check_interface (z, ptype, location, npts, pts, 1);
03168 free (pts);
03169
03170
03171
03172 for (nd = 1; nd <= ndataset; nd++)
03173 check_BCdataset (nb, nd, npts, dataclass, punits);
03174
03175
03176
03177 if (check_node ("BCProperty_t") == CG_OK) {
03178 puts (" checking BC property");
03179 fflush (stdout);
03180 go_absolute ("Zone_t", cgnszone, "ZoneBC_t", 1, "BC_t", nb,
03181 "BCProperty_t", 1, NULL);
03182 if (verbose > 1) {
03183 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03184 for (n = 1; n <= nd; n++) {
03185 if (cg_descriptor_read (n, name, &desc))
03186 error_exit("cg_descriptor_read");
03187 if (desc != NULL) {
03188 printf (" Descriptor %s:\n%s\n", name, desc);
03189 cg_free (desc);
03190 }
03191 }
03192 }
03193 check_user_data (dataclass, punits, 6);
03194
03195 ierr = cg_bc_wallfunction_read (cgnsfn, cgnsbase, cgnszone, nb,
03196 &wtype);
03197 if (ierr && ierr != CG_NODE_NOT_FOUND)
03198 error_exit("cg_bc_wallfunction_read");
03199 if (ierr == CG_OK) {
03200 puts (" checking Wall Function property");
03201 go_relative ("WallFunction_t", 1, NULL);
03202 if (verbose) {
03203 printf (" Wall Function Type=%s\n",
03204 cg_WallFunctionTypeName (wtype));
03205 if (verbose > 1) {
03206 if (cg_ndescriptors (&nd))
03207 error_exit("cg_ndescriptors");
03208 for (n = 1; n <= nd; n++) {
03209 if (cg_descriptor_read (n, name, &desc))
03210 error_exit("cg_descriptor_read");
03211 if (desc != NULL) {
03212 printf (" Descriptor %s:\n%s\n", name, desc);
03213 cg_free (desc);
03214 }
03215 }
03216 }
03217 }
03218 check_user_data (dataclass, punits, 8);
03219 go_relative ("..", 1, NULL);
03220 }
03221
03222 ierr = cg_bc_area_read (cgnsfn, cgnsbase, cgnszone, nb,
03223 &atype, &area, name);
03224 if (ierr && ierr != CG_NODE_NOT_FOUND)
03225 error_exit("cg_bc_area_read");
03226 if (ierr == CG_OK) {
03227 puts (" checking Area property");
03228 go_relative ("Area_t", 1, NULL);
03229 if (verbose) {
03230 printf (" Area Type=%s\n", cg_AreaTypeName (atype));
03231 printf (" Area=%g\n", area);
03232 printf (" Region=\"%s\"\n", name);
03233 if (verbose > 1) {
03234 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03235 for (n = 1; n <= nd; n++) {
03236 if (cg_descriptor_read (n, name, &desc))
03237 error_exit("cg_descriptor_read");
03238 if (desc != NULL) {
03239 printf (" Descriptor %s:\n%s\n", name, desc);
03240 cg_free (desc);
03241 }
03242 }
03243 }
03244 }
03245 check_quantity (1, "SurfaceArea", dataclass, punits, 1, 8);
03246 check_user_data (dataclass, punits, 8);
03247 go_relative ("..", 1, NULL);
03248 }
03249 }
03250 }
03251
03252
03253
03254 static void check_zoneBC (void)
03255 {
03256 char name[33], *desc;
03257 int n, nb, ierr;
03258 int *punits, units[9], dataclass;
03259
03260 if (cg_nbocos (cgnsfn, cgnsbase, cgnszone, &nb))
03261 error_exit("cg_nbocos");
03262 if (nb < 1) return;
03263 puts (" checking boundary conditions");
03264 fflush (stdout);
03265 go_absolute ("Zone_t", cgnszone, "ZoneBC_t", 1, NULL);
03266
03267 if (verbose > 1) {
03268 int nd;
03269 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03270 for (n = 1; n <= nd; n++) {
03271 if (cg_descriptor_read (n, name, &desc))
03272 error_exit("cg_descriptor_read");
03273 if (desc != NULL) {
03274 printf (" Descriptor %s:\n%s\n", name, desc);
03275 cg_free (desc);
03276 }
03277 }
03278 }
03279
03280 dataclass = read_dataclass ();
03281 punits = read_units (units);
03282 if (verbose) {
03283 if (dataclass >= 0) print_dataclass (dataclass, 4);
03284 if (punits) print_units (punits, 4);
03285 }
03286 if (dataclass < 0) dataclass = Zones[cgnszone-1].dataclass;
03287 if (punits == NULL) punits = Zones[cgnszone-1].punits;
03288
03289 ierr = cg_state_read (&desc);
03290 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_state_read");
03291 if (ierr == CG_OK) {
03292 puts (" checking reference state");
03293 if (desc != NULL) {
03294 if (verbose > 1)
03295 printf (" Descriptor:%s\n", desc);
03296 cg_free (desc);
03297 }
03298 fflush (stdout);
03299 go_relative ("ReferenceState_t", 1, NULL);
03300 check_arrays (dataclass, punits, 1, 0, 6);
03301 }
03302
03303 check_user_data (dataclass, punits, 4);
03304
03305 for (n = 1; n <= nb; n++)
03306 check_BC (n, dataclass, punits);
03307 }
03308
03309
03310
03311 static void check_1to1 (int nc)
03312 {
03313 char name[33], dname[33], *desc;
03314 int ierr, n, nd, range[6], drange[6], trans[3];
03315 ZONE *z = &Zones[cgnszone-1], *dz;
03316 #if CGNS_VERSION >= 2400
03317 int ndim, dims[12];
03318 float center[3], angle[3], translate[3];
03319 AverageInterfaceType_t average;
03320 DataType_t datatype;
03321 #endif
03322
03323 if (cg_1to1_read (cgnsfn, cgnsbase, cgnszone, nc, name,
03324 dname, range, drange, trans)) error_exit("cg_1to1_read");
03325 printf (" checking 1to1 connectivity \"%s\"\n", name);
03326 if (verbose) {
03327 printf (" Range=[%d:%d", range[0], range[z->idim]);
03328 for (n = 1; n < z->idim; n++)
03329 printf (",%d:%d", range[n], range[n+z->idim]);
03330 puts ("]");
03331 }
03332
03333 for (n = 0; n < z->idim; n++) {
03334 if (range[n] > range[n+z->idim]) {
03335 warning (1, "start value > end value for range");
03336 break;
03337 }
03338 }
03339 puts (" checking 1to1 interface");
03340 fflush (stdout);
03341 check_interface (z, PointRange, Vertex, 2, range, 1);
03342
03343 for (dz = NULL, n = 0; n < NumZones; n++) {
03344 if (0 == strcmp (dname, Zones[n].name)) {
03345 dz = &Zones[n];
03346 break;
03347 }
03348 }
03349 if (verbose)
03350 printf (" Donor Name=%s\n", dname);
03351 if (dz == NULL) {
03352 error ("donor zone \"%s\" not found", dname);
03353 if (verbose)
03354 puts (" Donor Range=<can't evaluate>");
03355 }
03356 else {
03357 if (verbose) {
03358 printf (" Donor Range=[%d:%d", drange[0], drange[dz->idim]);
03359 for (n = 1; n < dz->idim; n++)
03360 printf (",%d:%d", drange[n], drange[n+dz->idim]);
03361 puts ("]");
03362 }
03363 puts (" checking donor interface");
03364 fflush (stdout);
03365 check_interface (dz, PointRange, Vertex, 2, drange, 1);
03366 }
03367
03368 if (verbose) {
03369 printf (" Transform=[%d", trans[0]);
03370 for (n = 1; n < z->idim; n++)
03371 printf (",%d", trans[n]);
03372 puts ("]");
03373 }
03374
03375 if (dz != NULL) {
03376 int id, np = 1, dnp = 1;
03377 for (n = 0; n < z->idim; n++)
03378 np *= (abs(range[n+z->idim] - range[n]) + 1);
03379 for (n = 0; n < z->idim; n++)
03380 dnp *= (abs(drange[n+dz->idim] - drange[n]) + 1);
03381 if (np != dnp)
03382 error ("number of points is not the same as for the donor zone");
03383 for (n = 0; n < z->idim; n++) {
03384 np = range[n+z->idim] - range[n];
03385 id = abs (trans[n]);
03386 if ((id == 0 && np) || id > dz->idim)
03387 dnp = np + 1;
03388 else {
03389 id--;
03390 dnp = drange[id+dz->idim] - drange[id];
03391 if (trans[n] < 0) dnp = -dnp;
03392 }
03393 if (np != dnp) {
03394 error ("transform specification is invalid");
03395 break;
03396 }
03397 }
03398 }
03399
03400 go_absolute ("Zone_t", cgnszone, "ZoneGridConnectivity_t", 1,
03401 "GridConnectivity1to1_t", nc, NULL);
03402
03403 if (verbose > 1) {
03404 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03405 for (n = 1; n <= nd; n++) {
03406 if (cg_descriptor_read (n, name, &desc))
03407 error_exit("cg_descriptor_read");
03408 if (desc != NULL) {
03409 printf (" Descriptor %s:\n%s\n", name, desc);
03410 cg_free (desc);
03411 }
03412 }
03413 }
03414
03415 ierr = read_ordinal (&n);
03416 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_ordinal_read");
03417 if (ierr == CG_OK && verbose)
03418 printf (" Ordinal=%d\n", n);
03419
03420 check_user_data (z->dataclass, z->punits, 4);
03421
03422 #if CGNS_VERSION >= 2400
03423 if (check_node ("GridConnectivityProperty_t")) return;
03424 puts (" checking grid connectivity property");
03425 fflush (stdout);
03426 go_relative ("GridConnectivityProperty_t", 1, NULL);
03427 if (verbose > 1) {
03428 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03429 for (n = 1; n <= nd; n++) {
03430 if (cg_descriptor_read (n, name, &desc))
03431 error_exit("cg_descriptor_read");
03432 if (desc != NULL) {
03433 printf (" Descriptor %s:\n%s\n", name, desc);
03434 cg_free (desc);
03435 }
03436 }
03437 }
03438 check_user_data (z->dataclass, z->punits, 6);
03439
03440 ierr = cg_1to1_periodic_read (cgnsfn, cgnsbase, cgnszone, nc,
03441 center, angle, translate);
03442 if (ierr && ierr != CG_NODE_NOT_FOUND)
03443 error_exit("cg_1to1_periodic_read");
03444 if (ierr == CG_OK) {
03445 int *punits, units[9], dataclass;
03446
03447 puts (" checking periodic property");
03448 go_relative ("Periodic_t", 1, NULL);
03449 if (verbose) {
03450 printf (" Center=[%g", center[0]);
03451 for (n = 1; n < PhyDim; n++)
03452 printf (",%g", center[n]);
03453 printf ("]\n Angle=[%g", angle[0]);
03454 for (n = 1; n < PhyDim; n++)
03455 printf (",%g", angle[n]);
03456 printf ("]\n Translation=[%g", translate[0]);
03457 for (n = 1; n < PhyDim; n++)
03458 printf (",%g", translate[n]);
03459 puts ("]");
03460 if (verbose > 1) {
03461 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03462 for (n = 1; n <= nd; n++) {
03463 if (cg_descriptor_read (n, name, &desc))
03464 error_exit("cg_descriptor_read");
03465 if (desc != NULL) {
03466 printf (" Descriptor %s:\n%s\n", name, desc);
03467 cg_free (desc);
03468 }
03469 }
03470 }
03471 }
03472
03473 dataclass = read_dataclass ();
03474 punits = read_units (units);
03475 if (verbose) {
03476 if (dataclass >= 0) print_dataclass (dataclass, 8);
03477 if (punits) print_units (punits, 8);
03478 }
03479 if (dataclass < 0) dataclass = z->dataclass;
03480 if (punits == NULL) punits = z->punits;
03481
03482 if (cg_narrays (&nd)) error_exit("cg_narrays");
03483 for (n = 1; n <= nd; n++) {
03484 if (cg_array_info (n, name, &datatype, &ndim, dims))
03485 error_exit("cg_array_info");
03486 printf (" checking periodic data %s\n", name);
03487 check_quantity (n, name, dataclass, punits, 1, 8);
03488 }
03489 go_relative ("..", 1, NULL);
03490 }
03491
03492 ierr = cg_1to1_average_read (cgnsfn, cgnsbase, cgnszone, nc, &average);
03493 if (ierr && ierr != CG_NODE_NOT_FOUND)
03494 error_exit("cg_1to1_average_read");
03495 if (ierr == CG_OK) {
03496 puts (" checking average interface property");
03497 fflush (stdout);
03498 go_relative ("AverageInterface_t", 1, NULL);
03499 if (verbose) {
03500 printf (" Interface Type=%s\n",
03501 cg_AverageInterfaceTypeName (average));
03502 if (verbose > 1) {
03503 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03504 for (n = 1; n <= nd; n++) {
03505 if (cg_descriptor_read (n, name, &desc))
03506 error_exit("cg_descriptor_read");
03507 if (desc != NULL) {
03508 printf (" Descriptor %s:\n%s\n", name, desc);
03509 cg_free (desc);
03510 }
03511 }
03512 }
03513 }
03514 check_user_data (z->dataclass, z->punits, 8);
03515 }
03516 #endif
03517 }
03518
03519
03520
03521 static void check_conn (int nc)
03522 {
03523 char name[33], dname[33], *desc;
03524 int ierr, n, nd, npts, dnpts, ndim, dims[12];
03525 int interp, *pts, *dpts;
03526 GridLocation_t location;
03527 GridConnectivityType_t ctype;
03528 PointSetType_t ptype, dptype;
03529 ZoneType_t dztype;
03530 DataType_t datatype;
03531 float center[3], angle[3], trans[3];
03532 AverageInterfaceType_t average;
03533 ZONE *z = &Zones[cgnszone-1], *dz;
03534
03535 if (cg_conn_info (cgnsfn, cgnsbase, cgnszone, nc, name,
03536 &location, &ctype, &ptype, &npts, dname, &dztype,
03537 &dptype, &datatype, &dnpts)) error_exit("cg_conn_info");
03538 printf (" checking connectivity \"%s\"\n", name);
03539 if (verbose) {
03540 printf (" Connectivity Type=%s\n",
03541 cg_GridConnectivityTypeName(ctype));
03542 printf (" Grid Location=%s\n",
03543 cg_GridLocationName(location));
03544 printf (" Point Set Type=%s\n",
03545 cg_PointSetTypeName(ptype));
03546 printf (" Number Points=%d\n", npts);
03547 printf (" Donor Zone=\"%s\"\n", dname);
03548 printf (" Donor Zone Type=%s\n", cg_ZoneTypeName(dztype));
03549 printf (" Donor Point Set Type=%s\n",
03550 cg_PointSetTypeName(dptype));
03551 printf (" Donor Number Points=%d\n", dnpts);
03552 printf (" Donor Data Type=%s\n", cg_DataTypeName(datatype));
03553 }
03554 fflush (stdout);
03555
03556 go_absolute ("Zone_t", cgnszone, "ZoneGridConnectivity_t", 1,
03557 "GridConnectivity_t", nc, NULL);
03558 interp = check_interpolants ();
03559
03560 ierr = 0;
03561 if (ctype == Overset) {
03562 if (location != Vertex && location != CellCenter)
03563 warning (1, "grid location should be Vertex or CellCenter");
03564 }
03565 else if (ctype == Abutting || ctype == Abutting1to1) {
03566 if (FileVersion < 2200) {
03567 if (location != Vertex && location != CellCenter)
03568 warning (1,
03569 "grid location should be Vertex or CellCenter");
03570 }
03571 else if (FileVersion >= 2300) {
03572 switch (location) {
03573 case Vertex:
03574 break;
03575 case FaceCenter:
03576 if (z->type == Structured)
03577 warning (2,
03578 "use [IJK]FaceCenter with Structured grids");
03579 break;
03580 case IFaceCenter:
03581 if (z->type != Structured)
03582 error ("IFaceCenter only valid for Structured grids");
03583 break;
03584 case JFaceCenter:
03585 if (z->type != Structured || z->idim < 2)
03586 error ("JFaceCenter only valid for Structured grids"
03587 " with CellDim > 1");
03588 break;
03589 case KFaceCenter:
03590 if (z->type != Structured || z->idim < 3)
03591 error ("KFaceCenter only valid for Structured grids"
03592 " with CellDim > 2");
03593 break;
03594 case CellCenter:
03595 if (z->type == Structured)
03596 warning (2, "use [IJK]FaceCenter location rather"
03597 " than CellCenter");
03598 else
03599 warning (2, "use FaceCenter location rather than"
03600 " CellCenter");
03601 break;
03602 default:
03603 error ("grid location not Vertex,CellCenter,FaceCenter"
03604 " or [IJK]FaceCenter");
03605 }
03606 }
03607 else {
03608 if (location != Vertex && location != CellCenter &&
03609 location != FaceCenter)
03610 warning (1, "grid location should be Vertex, FaceCenter"
03611 " or CellCenter");
03612 }
03613 }
03614 else {
03615 error ("connectivity type not Overset,Abutting or Abutting1to1");
03616 ierr++;
03617 }
03618 if (location < Vertex || location >= EdgeCenter) ierr++;
03619
03620 if (ptype == PointRange) {
03621 if (npts != 2) {
03622 error ("number of points is not 2 for PointRange");
03623 ierr++;
03624 }
03625 }
03626 else if (ptype == PointList) {
03627 if (npts < 1) {
03628 error ("number of points is less than 1");
03629 ierr++;
03630 }
03631 }
03632 else {
03633 error ("point set type is not PointList or PointRange");
03634 ierr++;
03635 }
03636
03637 for (dz = NULL, n = 0; n < NumZones; n++) {
03638 if (0 == strcmp (dname, Zones[n].name)) {
03639 dz = &Zones[n];
03640 break;
03641 }
03642 }
03643 if (dz == NULL) {
03644 error ("donor zone \"%s\" not found", dname);
03645 ierr++;
03646 }
03647 else {
03648 if (dztype != dz->type) {
03649 error ("returned donor zone type does not match actual zone type");
03650 ierr++;
03651 }
03652 }
03653
03654 if (dptype == PointListDonor) {
03655 if (ctype != Abutting1to1 && FileVersion >= 2000)
03656 warning (1, "PointListDonor should only be used for Abutting1to1");
03657 if (interp)
03658 warning (1, "InterpolantsDonor given for PointListDonor");
03659 }
03660 else if (dptype == CellListDonor) {
03661 if (interp) {
03662 if (LibraryVersion < 2000)
03663 warning (1,
03664 "InterpolantsDonor given but they are not readable\n"
03665 " due to a bug in the CGNS library prior to 2.0");
03666 }
03667 else
03668 warning (1, "InterpolantsDonor not given for CellListDonor");
03669 }
03670 else {
03671 error ("donor point set type is not PointListDonor or CellListDonor");
03672 ierr++;
03673 }
03674
03675 if (dnpts < 1) {
03676 error ("donor number of points is less than 1");
03677 ierr++;
03678 }
03679 if (ierr) npts = 0;
03680
03681 if (verbose > 1) {
03682 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03683 for (n = 1; n <= nd; n++) {
03684 if (cg_descriptor_read (n, name, &desc))
03685 error_exit("cg_descriptor_read");
03686 if (desc != NULL) {
03687 printf (" Descriptor %s:\n%s\n", name, desc);
03688 cg_free (desc);
03689 }
03690 }
03691 }
03692
03693 ierr = read_ordinal (&n);
03694 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_ordinal_read");
03695 if (ierr == CG_OK && verbose)
03696 printf (" Ordinal=%d\n", n);
03697
03698 check_user_data (z->dataclass, z->punits, 4);
03699
03700 if (npts && dnpts) {
03701 pts = (int *) malloc (npts * z->idim * sizeof(int));
03702 if (LibraryVersion < 2200) {
03703
03704
03705 dpts = (int *) malloc (dnpts * CellDim * sizeof(int));
03706 }
03707 else
03708 dpts = (int *) malloc (dnpts * dz->idim * sizeof(int));
03709 if (NULL == pts || NULL == dpts) {
03710 fprintf (stderr, "malloc failed for connectivity points\n");
03711 exit (1);
03712 }
03713 if (cg_conn_read (cgnsfn, cgnsbase, cgnszone, nc, pts, Integer, dpts))
03714 error_exit("cg_conn_read");
03715
03716 puts (" checking connectivity interface");
03717 fflush (stdout);
03718 check_interface (z, ptype, location, npts, pts, ctype != Overset);
03719 free (pts);
03720
03721 puts (" checking donor zone interface");
03722 fflush (stdout);
03723 check_interface (dz, dptype, location, dnpts, dpts, ctype != Overset);
03724 free (dpts);
03725 }
03726
03727 if (check_node ("GridConnectivityProperty_t")) return;
03728 puts (" checking grid connectivity property");
03729 fflush (stdout);
03730 go_relative ("GridConnectivityProperty_t", 1, NULL);
03731 if (verbose > 1) {
03732 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03733 for (n = 1; n <= nd; n++) {
03734 if (cg_descriptor_read (n, name, &desc))
03735 error_exit("cg_descriptor_read");
03736 if (desc != NULL) {
03737 printf (" Descriptor %s:\n%s\n", name, desc);
03738 cg_free (desc);
03739 }
03740 }
03741 }
03742 check_user_data (z->dataclass, z->punits, 6);
03743
03744 ierr = cg_conn_periodic_read (cgnsfn, cgnsbase, cgnszone, nc,
03745 center, angle, trans);
03746 if (ierr && ierr != CG_NODE_NOT_FOUND)
03747 error_exit("cg_conn_periodic_read");
03748 if (ierr == CG_OK) {
03749 int *punits, units[9], dataclass;
03750
03751 puts (" checking periodic property");
03752 go_relative ("Periodic_t", 1, NULL);
03753 if (verbose) {
03754 printf (" Center=[%g", center[0]);
03755 for (n = 1; n < PhyDim; n++)
03756 printf (",%g", center[n]);
03757 printf ("]\n Angle=[%g", angle[0]);
03758 for (n = 1; n < PhyDim; n++)
03759 printf (",%g", angle[n]);
03760 printf ("]\n Translation=[%g", trans[0]);
03761 for (n = 1; n < PhyDim; n++)
03762 printf (",%g", trans[n]);
03763 puts ("]");
03764 if (verbose > 1) {
03765 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03766 for (n = 1; n <= nd; n++) {
03767 if (cg_descriptor_read (n, name, &desc))
03768 error_exit("cg_descriptor_read");
03769 if (desc != NULL) {
03770 printf (" Descriptor %s:\n%s\n", name, desc);
03771 cg_free (desc);
03772 }
03773 }
03774 }
03775 }
03776
03777 dataclass = read_dataclass ();
03778 punits = read_units (units);
03779 if (verbose) {
03780 if (dataclass >= 0) print_dataclass (dataclass, 8);
03781 if (punits) print_units (punits, 8);
03782 }
03783 if (dataclass < 0) dataclass = z->dataclass;
03784 if (punits == NULL) punits = z->punits;
03785
03786 if (cg_narrays (&nd)) error_exit("cg_narrays");
03787 for (n = 1; n <= nd; n++) {
03788 if (cg_array_info (n, name, &datatype, &ndim, dims))
03789 error_exit("cg_array_info");
03790 printf (" checking periodic data %s\n", name);
03791 check_quantity (n, name, dataclass, punits, 1, 8);
03792 }
03793 go_relative ("..", 1, NULL);
03794 }
03795
03796 ierr = cg_conn_average_read (cgnsfn, cgnsbase, cgnszone, nc, &average);
03797 if (ierr && ierr != CG_NODE_NOT_FOUND)
03798 error_exit("cg_conn_average_read");
03799 if (ierr == CG_OK) {
03800 puts (" checking average interface property");
03801 fflush (stdout);
03802 go_relative ("AverageInterface_t", 1, NULL);
03803 if (verbose) {
03804 printf (" Interface Type=%s\n",
03805 cg_AverageInterfaceTypeName (average));
03806 if (verbose > 1) {
03807 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03808 for (n = 1; n <= nd; n++) {
03809 if (cg_descriptor_read (n, name, &desc))
03810 error_exit("cg_descriptor_read");
03811 if (desc != NULL) {
03812 printf (" Descriptor %s:\n%s\n", name, desc);
03813 cg_free (desc);
03814 }
03815 }
03816 }
03817 }
03818 check_user_data (z->dataclass, z->punits, 8);
03819 }
03820 }
03821
03822
03823
03824 static void check_hole (int nh)
03825 {
03826 char name[33];
03827 int ierr, n, nptsets, npts, np;
03828 GridLocation_t location;
03829 PointSetType_t ptype;
03830 ZONE *z = &Zones[cgnszone-1];
03831
03832 if (cg_hole_info (cgnsfn, cgnsbase, cgnszone, nh, name,
03833 &location, &ptype, &nptsets, &npts)) error_exit("cg_hole_info");
03834 printf (" checking overset hole \"%s\"\n", name);
03835 if (verbose) {
03836 printf (" Grid Location=%s\n",
03837 cg_GridLocationName(location));
03838 printf (" Point Set Type=%s\n",
03839 cg_PointSetTypeName(ptype));
03840 printf (" Number Point Sets=%d\n", nptsets);
03841 }
03842 fflush (stdout);
03843
03844 ierr = np = 0;
03845 if (location != Vertex && location != CellCenter) {
03846 error ("location not Vertex or CellCenter");
03847 ierr++;
03848 }
03849 if (ptype == PointRange) {
03850 if (nptsets < 1)
03851 error ("nptsets must be greater then 0 for PointRange");
03852 if (npts != 2 * nptsets)
03853 error ("npts not equal to 2 * nptsets for PointRange");
03854 np = 2 * nptsets;
03855 }
03856 else if (ptype == PointList) {
03857 if (nptsets != 1)
03858 error ("nptsets must be 1 for PointList");
03859 if (npts < 1)
03860 error ("npts is less than 1 for PointList");
03861 nptsets = 1;
03862 np = npts;
03863 }
03864 else {
03865 error ("point set type not PointList or PointRange");
03866 ierr++;
03867 }
03868
03869 if (!ierr && np > 0) {
03870 int *pnts = (int *) malloc (np * z->idim * sizeof(int));
03871 if (pnts == NULL) {
03872 fprintf (stderr, "malloc failed for hole data\n");
03873 exit (1);
03874 }
03875 if (cg_hole_read (cgnsfn, cgnsbase, cgnszone, nh, pnts))
03876 error_exit("cg_hole_read");
03877 if (ptype == PointRange) npts = 2;
03878 for (np = 0, n = 1; n <= nptsets; n++) {
03879 printf (" checking point set %d interface\n", n);
03880 fflush (stdout);
03881 check_interface (z, ptype, location, npts, &pnts[np], CellDim);
03882 np += npts * z->idim;
03883 }
03884 free (pnts);
03885 }
03886
03887 go_absolute ("Zone_t", cgnszone, "ZoneGridConnectivity_t", 1,
03888 "OversetHoles_t", nh, NULL);
03889
03890 if (verbose > 1) {
03891 int nd;
03892 char *desc;
03893 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03894 for (n = 1; n <= nd; n++) {
03895 if (cg_descriptor_read (n, name, &desc))
03896 error_exit("cg_descriptor_read");
03897 if (desc != NULL) {
03898 printf (" Descriptor %s:\n%s\n", name, desc);
03899 cg_free (desc);
03900 }
03901 }
03902 }
03903
03904 check_user_data (z->dataclass, z->punits, 4);
03905 }
03906
03907
03908
03909 static void check_connectivity (void)
03910 {
03911 int ierr, n, nc;
03912
03913 ierr = cg_goto (cgnsfn, cgnsbase, "Zone_t", cgnszone,
03914 "ZoneGridConnectivity_t", 1, "end");
03915 if (ierr) {
03916 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_goto");
03917 return;
03918 }
03919 puts (" checking zone grid connectivty");
03920 fflush (stdout);
03921 go_absolute ("Zone_t", cgnszone, "ZoneGridConnectivity_t", 1, NULL);
03922
03923 if (verbose > 1) {
03924 int nd;
03925 char name[33], *desc;
03926 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
03927 for (n = 1; n <= nd; n++) {
03928 if (cg_descriptor_read (n, name, &desc))
03929 error_exit("cg_descriptor_read");
03930 if (desc != NULL) {
03931 printf (" Descriptor %s:\n%s\n", name, desc);
03932 cg_free (desc);
03933 }
03934 }
03935 }
03936
03937 check_user_data (Zones[cgnszone-1].dataclass, Zones[cgnszone-1].punits, 4);
03938
03939 if (cg_n1to1 (cgnsfn, cgnsbase, cgnszone, &nc)) error_exit("cg_n1to1");
03940 for (n = 1; n <= nc; n++)
03941 check_1to1 (n);
03942
03943 if (cg_nconns (cgnsfn, cgnsbase, cgnszone, &nc)) error_exit("cg_nconns");
03944 for (n = 1; n <= nc; n++)
03945 check_conn (n);
03946
03947 if (cg_nholes (cgnsfn, cgnsbase, cgnszone, &nc)) error_exit("cg_nholes");
03948 for (n = 1; n <= nc; n++)
03949 check_hole (n);
03950 }
03951
03952
03953
03954 static void check_arbitrary_motion (int na)
03955 {
03956 char name[33];
03957 int ierr, n, nd, id, rind[6];
03958 int datasize, size, ndim, dims[12];
03959 int *punits, units[9], dataclass;
03960 DataType_t datatype;
03961 ArbitraryGridMotionType_t type;
03962 GridLocation_t location;
03963 ZONE *z = &Zones[cgnszone-1];
03964
03965 if (cg_arbitrary_motion_read (cgnsfn, cgnsbase, cgnszone,
03966 na, name, &type)) error_exit("cg_arbitrary_motion_read");
03967 strcpy (ArbitraryGrid[na-1], name);
03968 printf (" checking arbitrary motion \"%s\"\n", name);
03969 if (verbose)
03970 printf (" Arbitrary Motion Type=%s\n",
03971 cg_ArbitraryGridMotionTypeName (type));
03972 fflush (stdout);
03973
03974 go_absolute ("Zone_t", cgnszone, "ArbitraryGridMotion_t", na, NULL);
03975
03976
03977
03978 ierr = read_gridlocation (&location);
03979 if (ierr) {
03980 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_gridlocation_read");
03981 location = Vertex;
03982 }
03983 else {
03984 if (verbose)
03985 printf (" Grid Location=%s\n", cg_GridLocationName(location));
03986 }
03987
03988
03989
03990 ierr = read_rind (rind);
03991 if (ierr) {
03992 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_rind_read");
03993 for (n = 0; n < 6; n++)
03994 rind[n] = 0;
03995 }
03996 else {
03997 if (verbose) {
03998 printf (" Rind=[%d", rind[0]);
03999 for (n = 1; n < 2 * z->idim; n++)
04000 printf (",%d", rind[n]);
04001 puts ("]");
04002 }
04003 if (z->type == Unstructured && FileVersion < 2400)
04004 error ("rind not valid for unstructured zones");
04005 }
04006
04007
04008
04009 if (verbose > 1) {
04010 char *desc;
04011 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
04012 for (n = 1; n <= nd; n++) {
04013 if (cg_descriptor_read (n, name, &desc))
04014 error_exit("cg_descriptor_read");
04015 if (desc != NULL) {
04016 printf (" Descriptor %s:\n%s\n", name, desc);
04017 cg_free (desc);
04018 }
04019 }
04020 }
04021
04022
04023
04024 dataclass = read_dataclass ();
04025 punits = read_units (units);
04026 if (verbose) {
04027 if (dataclass >= 0) print_dataclass (dataclass, 4);
04028 if (punits) print_units (punits, 4);
04029 }
04030 if (dataclass < 0) dataclass = z->dataclass;
04031 if (punits == NULL) punits = z->punits;
04032
04033
04034
04035 datasize = get_data_size (z, location, rind);
04036
04037 if (cg_narrays (&nd)) error_exit("cg_narrays");
04038 if (nd == 0 && type != DeformingGrid)
04039 warning (1, "grid velocity data is missing");
04040
04041 for (n = 1; n <= nd; n++) {
04042 if (cg_array_info (n, name, &datatype, &ndim, dims))
04043 error_exit("cg_array_info");
04044 printf (" checking grid velocity \"%s\"\n", name);
04045 fflush (stdout);
04046 for (size = 1, id = 0; id < ndim; id++)
04047 size *= dims[id];
04048 if (ndim != z->idim || size < 1 ||
04049 (datasize && size != datasize))
04050 error ("bad dimension values");
04051 check_quantity (n, name, dataclass, punits, 1, 6);
04052 }
04053
04054 check_user_data (dataclass, punits, 4);
04055 }
04056
04057
04058
04059 static void check_rigid_motion (int nr)
04060 {
04061 char name[33];
04062 int n, nd, i, ndim, dims[12], size;
04063 int dataclass, *punits, units[9];
04064 RigidGridMotionType_t type;
04065 DataType_t datatype;
04066 ZONE *z = &Zones[cgnszone-1];
04067
04068 if (cg_rigid_motion_read (cgnsfn, cgnsbase, cgnszone,
04069 nr, name, &type)) error_exit("cg_rigid_motion_read");
04070 strcpy (RigidGrid[nr-1], name);
04071 printf (" checking rigid motion \"%s\"\n", name);
04072 if (verbose)
04073 printf (" Rigid Motion Type=%s\n",
04074 cg_RigidGridMotionTypeName (type));
04075 fflush (stdout);
04076
04077 go_absolute ("Zone_t", cgnszone, "RigidGridMotion_t", nr, NULL);
04078
04079
04080
04081 if (verbose > 1) {
04082 char *desc;
04083 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
04084 for (n = 1; n <= nd; n++) {
04085 if (cg_descriptor_read (n, name, &desc))
04086 error_exit("cg_descriptor_read");
04087 if (desc != NULL) {
04088 printf (" Descriptor %s:\n%s\n", name, desc);
04089 cg_free (desc);
04090 }
04091 }
04092 }
04093
04094
04095
04096 dataclass = read_dataclass ();
04097 punits = read_units (units);
04098 if (verbose) {
04099 if (dataclass >= 0) print_dataclass (dataclass, 4);
04100 if (punits) print_units (punits, 4);
04101 }
04102 if (dataclass < 0) dataclass = z->dataclass;
04103 if (punits == NULL) punits = z->punits;
04104
04105 if (cg_narrays (&nd)) error_exit("cg_narrays");
04106 for (n = 1; n <= nd; n++) {
04107 if (cg_array_info (n, name, &datatype, &ndim, dims))
04108 error_exit("cg_array_info");
04109 printf (" checking rigid grid data \"%s\"\n", name);
04110 fflush (stdout);
04111 if (0 == strcmp (name, "OriginLocation")) {
04112 if (ndim != 2 || dims[0] != PhyDim || dims[1] != 2)
04113 error ("bad dimension values");
04114 check_quantity (n, name, dataclass, punits, 1, 6);
04115 }
04116 else if (0 == strcmp (name, "RigidRotationAngle") ||
04117 0 == strcmp (name, "RigidRotationRate") ||
04118 0 == strcmp (name, "RigidVelocity")) {
04119 if (ndim != 1 || dims[0] != PhyDim)
04120 error ("invalid dimension");
04121 check_quantity (n, name, dataclass, punits, 1, 6);
04122 }
04123 else {
04124 for (size = 1, i = 0; i < ndim; i++)
04125 size *= dims[i];
04126 if (ndim < 1 || size < 1)
04127 error ("bad dimension values");
04128 check_quantity (n, name, dataclass, punits, -1, 6);
04129 }
04130 }
04131
04132 check_user_data (dataclass, punits, 2);
04133 }
04134
04135
04136
04137 static void check_zone_iter (void)
04138 {
04139 char *p, *desc, name[33], buff[33];
04140 int ierr, n, na, nd, nn, ndim, dims[12], size;
04141 int dataclass, *punits, units[9];
04142 DataType_t datatype;
04143 ZONE *z = &Zones[cgnszone-1];
04144
04145 go_absolute ("Zone_t", cgnszone, "ZoneIterativeData_t", 1, NULL);
04146
04147 if (verbose > 1) {
04148 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
04149 for (n = 1; n <= nd; n++) {
04150 if (cg_descriptor_read (n, name, &desc))
04151 error_exit("cg_descriptor_read");
04152 if (desc != NULL) {
04153 printf (" Descriptor %s:\n%s\n", name, desc);
04154 cg_free (desc);
04155 }
04156 }
04157 }
04158
04159 dataclass = read_dataclass ();
04160 punits = read_units (units);
04161 if (verbose) {
04162 if (dataclass >= 0) print_dataclass (dataclass, 4);
04163 if (punits) print_units (punits, 4);
04164 }
04165 if (dataclass < 0) dataclass = z->dataclass;
04166 if (!punits) punits = z->punits;
04167
04168 if (cg_narrays (&na)) error_exit("cg_narrays");
04169 for (n = 1; n <= na; n++) {
04170 if (cg_array_info (n, name, &datatype, &ndim, dims))
04171 error_exit("cg_array_info");
04172 printf (" checking zone iterative data \"%s\"\n", name);
04173 fflush (stdout);
04174 for (size = 1, nd = 0; nd < ndim; nd++)
04175 size *= dims[nd];
04176 if (0 == strcmp (name, "ArbitraryGridMotionPointers") ||
04177 0 == strcmp (name, "FlowSolutionPointers") ||
04178 0 == strcmp (name, "GridCoordinatesPointers") ||
04179 0 == strcmp (name, "RigidGridMotionPointers")) {
04180 if (ndim != 2 || dims[0] != 32 || size < 1 ||
04181 (NumSteps && dims[1] != NumSteps))
04182 error ("invalid dimension values");
04183 else {
04184 desc = (char *) malloc (size);
04185 if (desc == NULL) {
04186 fprintf (stderr, "malloc failed for zone iter data\n");
04187 exit (1);
04188 }
04189 if (cg_array_read (n, desc)) error_exit("cg_array_read");
04190 ierr = 0;
04191 if (0 == strcmp (name, "ArbitraryGridMotionPointers")) {
04192 for (nd = 0; nd < dims[1]; nd++) {
04193 strncpy (buff, &desc[nd<<5], 32);
04194 buff[32] = 0;
04195 p = buff + strlen(buff);
04196 while (--p >= buff && isspace(*p))
04197 ;
04198 *++p = 0;
04199 for (nn = 0; nn < NumArbitraryGrid; nn++) {
04200 if (0 == strcmp (buff, ArbitraryGrid[nn])) break;
04201 }
04202 if (nn == NumArbitraryGrid) ierr++;
04203 }
04204 }
04205 else if (0 == strcmp (name, "FlowSolutionPointers")) {
04206 for (nd = 0; nd < dims[1]; nd++) {
04207 strncpy (buff, &desc[nd<<5], 32);
04208 buff[32] = 0;
04209 p = buff + strlen(buff);
04210 while (--p >= buff && isspace(*p))
04211 ;
04212 *++p = 0;
04213 for (nn = 0; nn < NumFlowSolution; nn++) {
04214 if (0 == strcmp (buff, FlowSolution[nn])) break;
04215 }
04216 if (nn == NumFlowSolution) ierr++;
04217 }
04218 }
04219 else if (0 == strcmp (name, "GridCoordinatesPointers")) {
04220 for (nd = 0; nd < dims[1]; nd++) {
04221 strncpy (buff, &desc[nd<<5], 32);
04222 buff[32] = 0;
04223 p = buff + strlen(buff);
04224 while (--p >= buff && isspace(*p))
04225 ;
04226 *++p = 0;
04227 for (nn = 0; nn < NumGridCoordinate; nn++) {
04228 if (0 == strcmp (buff, GridCoordinate[nn])) break;
04229 }
04230 if (nn == NumGridCoordinate) ierr++;
04231 }
04232 }
04233 else {
04234 for (nd = 0; nd < dims[1]; nd++) {
04235 strncpy (buff, &desc[nd<<5], 32);
04236 buff[32] = 0;
04237 p = buff + strlen(buff);
04238 while (--p >= buff && isspace(*p))
04239 ;
04240 *++p = 0;
04241 for (nn = 0; nn < NumRigidGrid; nn++) {
04242 if (0 == strcmp (buff, RigidGrid[nn])) break;
04243 }
04244 if (nn == NumRigidGrid) ierr++;
04245 }
04246 }
04247 free (desc);
04248 if (ierr)
04249 error ("%d %s are invalid", ierr, name);
04250 }
04251 }
04252 else {
04253 if (ndim < 1 || size < 1)
04254 error ("invalid dimension values");
04255 check_quantity (n, name, dataclass, punits, 0, 6);
04256 }
04257 }
04258
04259 check_user_data (dataclass, punits, 4);
04260 }
04261
04262
04263
04264 static void check_discrete (int ndis)
04265 {
04266 char name[33];
04267 int n, nd, id, ierr, rind[6];
04268 int datasize, size, ndim, dims[12];
04269 int *punits, units[9], dataclass;
04270 DataType_t datatype;
04271 GridLocation_t location;
04272 ZONE *z = &Zones[cgnszone-1];
04273
04274 if (cg_discrete_read (cgnsfn, cgnsbase, cgnszone, ndis, name))
04275 error_exit("cg_discrete_read");
04276 printf (" checking discrete data \"%s\"\n", name);
04277 fflush (stdout);
04278
04279 go_absolute ("Zone_t", cgnszone, "DiscreteData_t", ndis, NULL);
04280
04281
04282
04283 ierr = read_gridlocation (&location);
04284 if (ierr) {
04285 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_gridlocation_read");
04286 location = Vertex;
04287 }
04288 else {
04289 if (verbose)
04290 printf (" Grid Location=%s\n", cg_GridLocationName(location));
04291 }
04292
04293
04294
04295 ierr = read_rind (rind);
04296 if (ierr) {
04297 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_rind_read");
04298 for (n = 0; n < 6; n++)
04299 rind[n] = 0;
04300 }
04301 else {
04302 if (verbose) {
04303 printf (" Rind=[%d", rind[0]);
04304 for (n = 1; n < 2 * z->idim; n++)
04305 printf (",%d", rind[n]);
04306 puts ("]");
04307 }
04308 if (z->type == Unstructured && FileVersion < 2400)
04309 error ("rind not valid for unstructured zones");
04310 }
04311
04312
04313
04314 if (verbose > 1) {
04315 char *desc;
04316 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
04317 for (n = 1; n <= nd; n++) {
04318 if (cg_descriptor_read (n, name, &desc))
04319 error_exit("cg_descriptor_read");
04320 if (desc != NULL) {
04321 printf (" Descriptor %s:\n%s\n", name, desc);
04322 cg_free (desc);
04323 }
04324 }
04325 }
04326
04327
04328
04329 dataclass = read_dataclass ();
04330 punits = read_units (units);
04331 if (verbose) {
04332 if (dataclass >= 0) print_dataclass (dataclass, 4);
04333 if (punits) print_units (punits, 4);
04334 }
04335 if (dataclass < 0) dataclass = z->dataclass;
04336 if (punits == NULL) punits = z->punits;
04337
04338
04339
04340 datasize = get_data_size (z, location, rind);
04341
04342 if (cg_narrays (&nd)) error_exit("cg_narrays");
04343 if (nd == 0)
04344 warning (2, "no discrete data arrays defined");
04345
04346 for (n = 1; n <= nd; n++) {
04347 if (cg_array_info (n, name, &datatype, &ndim, dims))
04348 error_exit("cg_array_info");
04349 printf (" checking discrete data array \"%s\"\n", name);
04350 fflush (stdout);
04351 for (size = 1, id = 0; id < ndim; id++)
04352 size *= dims[id];
04353 if (ndim != z->idim || size < 1 ||
04354 (datasize && size != datasize))
04355 error ("bad dimension values");
04356 check_quantity (n, name, dataclass, punits, -1, 6);
04357 }
04358
04359 check_user_data (dataclass, punits, 4);
04360 }
04361
04362
04363
04364 static void check_solution (int ns)
04365 {
04366 char name[33];
04367 int n, nf, id, ierr, rind[6];
04368 int datasize, size, ndim, dims[12];
04369 int *punits, units[9], dataclass;
04370 DataType_t datatype;
04371 GridLocation_t location;
04372 ZONE *z = &Zones[cgnszone-1];
04373
04374 if (cg_sol_info (cgnsfn, cgnsbase, cgnszone, ns, name, &location))
04375 error_exit("cg_sol_info");
04376 strcpy (FlowSolution[ns-1], name);
04377 printf (" checking solution \"%s\"\n", name);
04378 if (verbose)
04379 printf (" Grid Location=%s\n", cg_GridLocationName (location));
04380 fflush (stdout);
04381
04382 if (location != Vertex && location != CellCenter) {
04383 if (z->type == Unstructured)
04384 error ("grid location nust be Vertex or CellCenter for"
04385 " unstructured zones");
04386 else if (location != IFaceCenter &&
04387 location != JFaceCenter && location != KFaceCenter)
04388 error ("grid location not Vertex,CellCenter or [IJK]FaceCenter");
04389 }
04390
04391 go_absolute ("Zone_t", cgnszone, "FlowSolution_t", ns, NULL);
04392
04393
04394
04395 ierr = read_rind (rind);
04396 if (ierr) {
04397 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_rind_read");
04398 for (n = 0; n < 6; n++)
04399 rind[n] = 0;
04400 }
04401 else {
04402 if (verbose) {
04403 printf (" Rind=[%d", rind[0]);
04404 for (n = 1; n < 2 * z->idim; n++)
04405 printf (",%d", rind[n]);
04406 puts ("]");
04407 }
04408 if (z->type == Unstructured && FileVersion < 2400)
04409 error ("rind not valid for unstructured zones");
04410 }
04411
04412
04413
04414 if (verbose > 1) {
04415 char *desc;
04416 int nd;
04417 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
04418 for (n = 1; n <= nd; n++) {
04419 if (cg_descriptor_read (n, name, &desc))
04420 error_exit("cg_descriptor_read");
04421 if (desc != NULL) {
04422 printf (" Descriptor %s:\n%s\n", name, desc);
04423 cg_free (desc);
04424 }
04425 }
04426 }
04427
04428
04429
04430 dataclass = read_dataclass ();
04431 punits = read_units (units);
04432 if (verbose) {
04433 if (dataclass >= 0) print_dataclass (dataclass, 4);
04434 if (punits) print_units (punits, 4);
04435 }
04436 if (dataclass < 0) dataclass = z->dataclass;
04437 if (punits == NULL) punits = z->punits;
04438
04439
04440
04441 datasize = get_data_size (z, location, rind);
04442
04443
04444
04445 if (cg_nfields (cgnsfn, cgnsbase, cgnszone, ns, &nf))
04446 error_exit("cg_nfields");
04447 if (nf == 0)
04448 warning (2, "no solution data arrays defined");
04449
04450 for (n = 1; n <= nf; n++) {
04451 if (cg_array_info (n, name, &datatype, &ndim, dims))
04452 error_exit("cg_array_info");
04453 printf (" checking solution field \"%s\"\n", name);
04454 fflush (stdout);
04455 for (size = 1, id = 0; id < ndim; id++)
04456 size *= dims[id];
04457 if (ndim != z->idim || size < 1 ||
04458 (datasize && size != datasize))
04459 error ("bad dimension values");
04460 check_quantity (n, name, dataclass, punits, 1, 6);
04461 }
04462
04463
04464
04465 check_user_data (dataclass, punits, 4);
04466 }
04467
04468
04469
04470 static void check_zone (void)
04471 {
04472 char name[33], *desc;
04473 int n, nd, niter, ierr, eqset[7];
04474 float point[3], vector[3];
04475 ZONE *z = &Zones[cgnszone-1];
04476 static char indexname[] = "IJK";
04477
04478 printf ("checking zone \"%s\"\n", z->name);
04479 fflush (stdout);
04480
04481 if (z->type == Structured) {
04482 for (n = 0; n < CellDim; n++) {
04483 if (z->dims[0][n] < 2) {
04484 error ("number of points in %c-direction < 2", indexname[n]);
04485 z->idim = 0;
04486 }
04487 if (z->dims[1][n] != z->dims[0][n] - 1) {
04488 error ("number of cells in %c-direction is %d instead of %d",
04489 indexname[n], z->dims[1][n], z->dims[0][n] - 1);
04490 z->dims[1][n] = z->dims[0][n] - 1;
04491 }
04492 if (z->dims[2][n] != 0)
04493 warning (1, "VertexSizeBoundary in %c-direction should be 0"
04494 " for structured grid", indexname[n]);
04495 }
04496 }
04497 else if (z->type == Unstructured) {
04498 if (z->dims[0][0] < CellDim + 1) {
04499 error ("number of vertices < CellDim + 1");
04500 z->idim = 0;
04501 }
04502 if (z->dims[1][0] < 1) {
04503 warning (1, "number of cells < 1");
04504 z->idim = 0;
04505 }
04506 if (z->dims[2][0] > z->dims[0][0])
04507 error ("VertexBoundarySize > total number of vertices");
04508 }
04509 else
04510 error ("zone type is not Structured or Unstructured");
04511 if (z->idim == 0) return;
04512
04513
04514
04515 go_absolute ("Zone_t", cgnszone, NULL);
04516 if (verbose > 1) {
04517 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
04518 for (n = 1; n <= nd; n++) {
04519 if (cg_descriptor_read (n, name, &desc))
04520 error_exit("cg_descriptor_read");
04521 if (desc != NULL) {
04522 printf (" Descriptor %s:\n%s\n", name, desc);
04523 cg_free (desc);
04524 }
04525 }
04526 }
04527
04528
04529
04530 z->dataclass = read_dataclass ();
04531 z->punits = read_units (z->units);
04532 if (verbose) {
04533 printf (" Zone Type=%s\n", cg_ZoneTypeName(z->type));
04534 printf (" Vertex Size=[%d", z->dims[0][0]);
04535 for (n = 1; n < z->idim; n++)
04536 printf (",%d", z->dims[0][n]);
04537 puts ("]");
04538 printf (" Cell Size=[%d", z->dims[1][0]);
04539 for (n = 1; n < z->idim; n++)
04540 printf (",%d", z->dims[1][n]);
04541 puts ("]");
04542 if (z->dataclass >= 0) print_dataclass (z->dataclass, 2);
04543 if (z->punits) print_units (z->punits, 2);
04544 }
04545 if (z->dataclass < 0) z->dataclass = BaseClass;
04546 if (!z->punits) z->punits = pBaseUnits;
04547
04548
04549
04550 ierr = cg_famname_read (name);
04551 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_famname_read");
04552 if (ierr == CG_OK) {
04553 if (verbose) printf (" Family=%s\n", name);
04554 for (n = 0; n < NumFamily; n++) {
04555 if (0 == strcmp (name, Family[n])) break;
04556 }
04557 if (n >= NumFamily &&
04558 (FileVersion >= 1200 || strcmp(name, "ORPHAN")))
04559 warning (1, "zone family name \"%s\" not found", name);
04560 }
04561
04562
04563
04564 ierr = cg_state_read (&desc);
04565 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_state_read");
04566 if (ierr == CG_OK) {
04567 puts (" checking reference state");
04568 if (desc != NULL) {
04569 if (verbose > 1)
04570 printf (" Descriptor:%s\n", desc);
04571 cg_free (desc);
04572 }
04573 fflush (stdout);
04574 go_relative ("ReferenceState_t", 1, NULL);
04575 check_arrays (BaseClass, pBaseUnits, 1, 0, 4);
04576 }
04577
04578
04579
04580 go_absolute ("Zone_t", cgnszone, NULL);
04581 ierr = cg_equationset_read (&eqset[0], &eqset[1], &eqset[2],
04582 &eqset[3], &eqset[4], &eqset[5], &eqset[6]);
04583 if (ierr && ierr != CG_NODE_NOT_FOUND)
04584 error_exit("cg_equationset_read");
04585 if (ierr == CG_OK) {
04586 puts (" checking equation set");
04587 fflush (stdout);
04588 check_equation_set (eqset, z->dataclass, z->punits, 4);
04589 }
04590
04591
04592
04593 if (cg_ngrids (cgnsfn, cgnsbase, cgnszone,
04594 &NumGridCoordinate)) error_exit("cg_ngrids");
04595 if (!NumGridCoordinate)
04596 error ("no grid coordinates defined");
04597 else {
04598 create_names (NumGridCoordinate, &MaxGridCoordinate, &GridCoordinate);
04599 for (n = 1; n <= NumGridCoordinate; n++)
04600 check_coordinates (n);
04601 }
04602
04603
04604
04605 if (z->nsets) check_elements ();
04606
04607
04608
04609 check_zoneBC ();
04610
04611
04612
04613 check_connectivity ();
04614
04615
04616
04617 go_absolute ("Zone_t", cgnszone, NULL);
04618 ierr = cg_rotating_read (vector, point);
04619 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_rotating_read");
04620 if (ierr == CG_OK) {
04621 puts (" checking rotating coordinates");
04622 fflush (stdout);
04623 check_rotating (point, vector, z->dataclass, z->punits, 4);
04624 }
04625
04626
04627
04628 if (cg_n_arbitrary_motions (cgnsfn, cgnsbase, cgnszone,
04629 &NumArbitraryGrid)) error_exit("cg_n_arbitrary_motions");
04630 create_names (NumArbitraryGrid, &MaxArbitraryGrid, &ArbitraryGrid);
04631 for (n = 1; n <= NumArbitraryGrid; n++)
04632 check_arbitrary_motion (n);
04633
04634
04635
04636 if (cg_n_rigid_motions (cgnsfn, cgnsbase, cgnszone,
04637 &NumRigidGrid)) error_exit("cg_n_rigid_motions");
04638 create_names (NumRigidGrid, &MaxRigidGrid, &RigidGrid);
04639 for (n = 1; n <= NumRigidGrid; n++)
04640 check_rigid_motion (n);
04641
04642
04643
04644 if (cg_nsols (cgnsfn, cgnsbase, cgnszone,
04645 &NumFlowSolution)) error_exit("cg_nsols");
04646 create_names (NumFlowSolution, &MaxFlowSolution, &FlowSolution);
04647 for (n = 1; n <= NumFlowSolution; n++)
04648 check_solution (n);
04649
04650
04651
04652 go_absolute ("Zone_t", cgnszone, NULL);
04653 ierr = cg_convergence_read (&niter, &desc);
04654 if (ierr) {
04655 if (ierr != CG_NODE_NOT_FOUND) error_exit("cg_convergence_read");
04656 niter = 0;
04657 }
04658 else {
04659 puts (" checking zone convergence history");
04660 fflush (stdout);
04661 go_relative ("ConvergenceHistory_t", 1, NULL);
04662 check_convergence (niter, desc, z->dataclass, z->punits, 4);
04663 if (desc != NULL) cg_free (desc);
04664 }
04665
04666
04667
04668 ierr = cg_ziter_read (cgnsfn, cgnsbase, cgnszone, name);
04669
04670 if (ierr && ierr != CG_NODE_NOT_FOUND && LibraryVersion >= 2300)
04671 error_exit("cg_ziter_read");
04672 if (ierr == CG_OK) {
04673 printf (" checking zone iterative data \"%s\"\n", name);
04674 fflush (stdout);
04675 if (BaseIter)
04676 error ("ZoneIterativeData requires BaseIterativeData");
04677 check_zone_iter ();
04678 }
04679
04680
04681
04682 go_absolute ("Zone_t", cgnszone, NULL);
04683 check_integral (z->dataclass, z->punits, 2);
04684
04685
04686
04687 go_absolute ("Zone_t", cgnszone, NULL);
04688 check_user_data (z->dataclass, z->punits, 2);
04689
04690
04691
04692 if (cg_ndiscrete (cgnsfn, cgnsbase, cgnszone, &nd))
04693 error_exit("cg_ndiscrete");
04694 for (n = 1; n <= nd; n++)
04695 check_discrete (n);
04696 }
04697
04698
04699
04700 static void check_axisymmetry (float *point, float *vector)
04701 {
04702 char name[33];
04703 int n, na, ndim, dims[12];
04704 int dataclass, *punits, units[9];
04705 DataType_t datatype;
04706
04707 if (verbose) {
04708 printf (" Reference Point=[%g,%g]\n", point[0], point[1]);
04709 printf (" Axis Vector=[%g,%g]\n", vector[0], vector[1]);
04710 }
04711
04712 go_absolute ("Axisymmetry_t", 1, NULL);
04713
04714 if (verbose > 1) {
04715 int nd;
04716 char *desc;
04717 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
04718 for (n = 1; n <= nd; n++) {
04719 if (cg_descriptor_read (n, name, &desc))
04720 error_exit("cg_descriptor_read");
04721 if (desc != NULL) {
04722 printf (" Descriptor %s:\n%s\n", name, desc);
04723 cg_free (desc);
04724 }
04725 }
04726 }
04727
04728 dataclass = read_dataclass ();
04729 punits = read_units (units);
04730 if (verbose) {
04731 if (dataclass >= 0) print_dataclass (dataclass, 2);
04732 if (punits) print_units (punits, 2);
04733 }
04734 if (dataclass < 0) dataclass = BaseClass;
04735 if (!punits) punits = pBaseUnits;
04736
04737 if (cg_narrays (&na)) error_exit("cg_narrays");
04738 for (n = 1; n <= na; n++) {
04739 if (cg_array_info (n, name, &datatype, &ndim, dims))
04740 error_exit("cg_array_info");
04741 printf (" checking axisymmetry data \"%s\"\n", name);
04742 fflush (stdout);
04743 if (0 == strcmp (name, "AxisymmetryAxisVector") ||
04744 0 == strcmp (name, "AxisymmetryReferencePoint")) {
04745 if (ndim != 1 || dims[0] != 2)
04746 error ("bad dimension values");
04747 if (datatype != RealSingle)
04748 error ("data type not real");
04749 check_quantity (n, name, dataclass, punits, 1, 4);
04750 }
04751 else if (0 == strcmp (name, "AxisymmetryAngle")) {
04752 if (ndim != 1 || dims[0] != 1)
04753 error ("bad dimension values");
04754 if (datatype != RealSingle)
04755 error ("data type not real");
04756 check_quantity (n, name, dataclass, punits, 1, 4);
04757 }
04758 else if (0 == strcmp (name, "CoordinateNames")) {
04759 if (ndim != 2 || dims[0] != 32 || dims[1] != 2)
04760 error ("bad dimension values");
04761 if (datatype != Character)
04762 error ("data type not character");
04763 }
04764 else
04765 warning (1, "not valid as child of Axisymmetry");
04766 }
04767
04768 check_user_data (dataclass, punits, 2);
04769 }
04770
04771
04772
04773 static void check_gravity (float *vector)
04774 {
04775 char *desc, name[33];
04776 int n, na, nd, ndim, dims[12];
04777 int dataclass, *punits, units[9];
04778 DataType_t datatype;
04779
04780 if (verbose) {
04781 printf (" Vector=[%g]", vector[0]);
04782 for (nd = 1; nd < PhyDim; nd++)
04783 printf (",%g", vector[nd]);
04784 puts ("]");
04785 }
04786
04787 go_absolute ("Gravity_t", 1, NULL);
04788
04789 if (verbose > 1) {
04790 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
04791 for (n = 1; n <= nd; n++) {
04792 if (cg_descriptor_read (n, name, &desc))
04793 error_exit("cg_descriptor_read");
04794 if (desc != NULL) {
04795 printf (" Descriptor %s:\n%s\n", name, desc);
04796 cg_free (desc);
04797 }
04798 }
04799 }
04800
04801 dataclass = read_dataclass ();
04802 punits = read_units (units);
04803 if (verbose) {
04804 if (dataclass >= 0) print_dataclass (dataclass, 2);
04805 if (punits) print_units (punits, 2);
04806 }
04807 if (dataclass < 0) dataclass = BaseClass;
04808 if (!punits) punits = pBaseUnits;
04809
04810 if (cg_narrays (&na)) error_exit("cg_narrays");
04811 for (n = 1; n <= na; n++) {
04812 if (cg_array_info (n, name, &datatype, &ndim, dims))
04813 error_exit("cg_array_info");
04814 printf (" checking gravity data \"%s\"\n", name);
04815 fflush (stdout);
04816 if (0 == strcmp (name, "GravityVector")) {
04817 if (ndim != 1 || dims[0] != PhyDim)
04818 error ("invalid dimension values");
04819 if (datatype != RealSingle)
04820 error ("data type is not RealSingle");
04821 check_quantity (n, name, dataclass, punits, 1, 4);
04822 }
04823 else
04824 warning (1, "not valid as child of Gravity");
04825 }
04826
04827 check_user_data (dataclass, punits, 2);
04828 }
04829
04830
04831
04832 static void check_family (int fam)
04833 {
04834 char famname[33], name[33], cad[33], *filename;
04835 int ierr, i, n, nbc, ngeo, nparts;
04836 BCType_t bctype;
04837 #if CGNS_VERSION >= 2400
04838 int nds, dirichlet, neumann;
04839 float point[3], vector[3];
04840 #endif
04841
04842 if (cg_family_read (cgnsfn, cgnsbase, fam, famname, &nbc, &ngeo))
04843 error_exit("cg_family_read");
04844 printf ("checking family \"%s\"\n", famname);
04845
04846 go_absolute ("Family_t", fam, NULL);
04847 if (verbose > 1) {
04848 int nd;
04849 char *desc;
04850 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
04851 for (n = 1; n <= nd; n++) {
04852 if (cg_descriptor_read (n, name, &desc))
04853 error_exit("cg_descriptor_read");
04854 if (desc != NULL) {
04855 printf (" Descriptor %s:\n%s\n", name, desc);
04856 cg_free (desc);
04857 }
04858 }
04859 }
04860
04861 if (verbose)
04862 printf (" Number BC=%d\n", nbc);
04863 if (nbc < 0 || nbc > 1)
04864 error ("number of BCs not 0 or 1 for %s", famname);
04865 for (n = 1; n <= nbc; n++) {
04866 if (cg_fambc_read (cgnsfn, cgnsbase, fam, n, name, &bctype))
04867 error_exit("cg_fambc_read");
04868 if (verbose) {
04869 printf (" BC Name=\"%s\"\n", name);
04870 printf (" BC Type=%s\n", cg_BCTypeName(bctype));
04871 }
04872 #if CGNS_VERSION >= 2400
04873 go_relative ("FamilyBC_t", n, NULL);
04874 ierr = cg_bcdataset_info (&nds);
04875 if (ierr && ierr != CG_NODE_NOT_FOUND)
04876 error_exit("cg_bcdataset_info");
04877 if (ierr == CG_OK && nds > 0) {
04878 for (i = 1; i <= nds; i++) {
04879 if (cg_bcdataset_read (i, name, &bctype, &dirichlet, &neumann))
04880 error_exit("cg_bcdataset_read");
04881 printf (" checking BC data set \"%s\"\n", name);
04882 fflush (stdout);
04883 go_relative ("BCDataSet_t", i, NULL);
04884 check_BCdata (bctype, dirichlet, neumann, 1,
04885 BaseClass, pBaseUnits, 4);
04886 go_relative ("..", i, NULL);
04887 }
04888 }
04889 go_relative ("..", 1, NULL);
04890 #endif
04891 }
04892
04893 if (verbose) printf (" Number Geo=%d\n", ngeo);
04894 for (n = 1; n <= ngeo; n++) {
04895 if (cg_geo_read (cgnsfn, cgnsbase, fam, n, name, &filename,
04896 cad, &nparts)) error_exit("cg_geo_read");
04897 if (verbose) {
04898 printf (" Geo Name=\"%s\"\n", name);
04899 printf (" Geo File=\"%s\"\n",
04900 filename == NULL ? "<unknown>" : filename);
04901 printf (" CAD=\"%s\"\n", cad);
04902 printf (" Nparts=%d\n", nparts);
04903 }
04904 if (filename != NULL) cg_free (filename);
04905 for (i = 1; i <= nparts; i++) {
04906 if (cg_part_read (cgnsfn, cgnsbase, fam, n, i, name))
04907 error_exit("cg_part_read");
04908 if (verbose > 2)
04909 printf (" Part %d Name=\"%s\"\n", i, name);
04910 }
04911 }
04912
04913 ierr = read_ordinal (&i);
04914 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_ordinal_read");
04915
04916 #if CGNS_VERSION >= 2400
04917 ierr = cg_rotating_read (vector, point);
04918 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_rotating_read");
04919 if (ierr == CG_OK) {
04920 puts (" checking rotating coordinates");
04921 fflush (stdout);
04922 check_rotating (point, vector, BaseClass, pBaseUnits, 4);
04923 }
04924 #endif
04925
04926 check_user_data (BaseClass, pBaseUnits, 2);
04927 }
04928
04929
04930
04931 static void check_base_iter (void)
04932 {
04933 char *p, *desc, name[33];
04934 int ierr, n, na, ns, nd, nmax, ndim, dims[12];
04935 int dataclass, *punits, units[9];
04936 int *icnt, nnf = 0, nfp = 0, nnz = 0, nzp = 0;
04937 DataType_t datatype;
04938
04939 if (verbose) printf (" Number Steps=%d\n", NumSteps);
04940 if (NumSteps < 1)
04941 warning (2, "number of time steps is not > 0");
04942
04943 go_absolute ("BaseIterativeData_t", 1, NULL);
04944 if (verbose > 1) {
04945 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
04946 for (n = 1; n <= nd; n++) {
04947 if (cg_descriptor_read (n, name, &desc))
04948 error_exit("cg_descriptor_read");
04949 if (desc != NULL) {
04950 printf (" Descriptor %s:\n%s\n", name, desc);
04951 cg_free (desc);
04952 }
04953 }
04954 }
04955
04956 dataclass = read_dataclass ();
04957 punits = read_units (units);
04958 if (verbose) {
04959 if (dataclass >= 0) print_dataclass (dataclass, 2);
04960 if (punits) print_units (punits, 2);
04961 }
04962 if (dataclass < 0) dataclass = BaseClass;
04963 if (!punits) punits = pBaseUnits;
04964
04965 if (cg_narrays (&na)) error_exit("cg_narrays");
04966 ns = 0;
04967 for (n = 1; n <= na; n++) {
04968 if (cg_array_info (n, name, &datatype, &ndim, dims))
04969 error_exit("cg_array_info");
04970 if (0 == strcmp (name, "NumberOfFamilies")) {
04971 nnf = n;
04972 continue;
04973 }
04974 if (0 == strcmp (name, "FamilyPointers")) {
04975 nfp = n;
04976 continue;
04977 }
04978 if (0 == strcmp (name, "NumberOfZones")) {
04979 nnz = n;
04980 continue;
04981 }
04982 if (0 == strcmp (name, "ZonePointers")) {
04983 nzp = n;
04984 continue;
04985 }
04986 printf (" checking \"%s\"\n", name);
04987 fflush (stdout);
04988 if (0 == strcmp (name, "IterationValues")) {
04989 if (ndim != 1 || dims[0] != NumSteps)
04990 error ("invalid dimension values");
04991 if (datatype != Integer)
04992 error ("data type not integer");
04993 ns++;
04994 }
04995 else if (0 == strcmp (name, "TimeValues")) {
04996 if (ndim != 1 || dims[0] != NumSteps)
04997 error ("invalid dimension values");
04998 if (datatype != RealSingle && datatype != RealDouble)
04999 error ("data type not real or double");
05000 ns++;
05001 }
05002 else {
05003 check_quantity (n, name, dataclass, punits, 0, 4);
05004 }
05005 }
05006 if (!ns)
05007 error ("TimeValues and/or IterationValues is required");
05008
05009
05010
05011 if (nnf && !nfp)
05012 error ("NumberOfFamilies given but not FamilyPointers");
05013 if (!nnf && nfp)
05014 error ("FamilyPointers given but not NumberOfFamilies");
05015 if (nnf && nfp) {
05016 ierr = nmax = 0;
05017 icnt = NULL;
05018 puts (" checking \"NumberOfFamilies\"");
05019 fflush (stdout);
05020 if (cg_array_info (nnf, name, &datatype, &ndim, dims))
05021 error_exit("cg_array_info");
05022 if (ndim != 1 || dims[0] != NumSteps) {
05023 error ("invalid dimension values");
05024 ierr = 1;
05025 }
05026 if (datatype != Integer) {
05027 error ("data type not integer");
05028 ierr = 1;
05029 }
05030 if (!ierr && NumSteps > 0) {
05031 icnt = (int *) malloc (NumSteps * sizeof(int));
05032 if (icnt == NULL) {
05033 fprintf (stderr, "malloc failed for number of families\n");
05034 exit (1);
05035 }
05036 if (cg_array_read (nnf, icnt)) error_exit("cg_array_read");
05037 for (ns = 0; ns < NumSteps; ns++) {
05038 if (icnt[ns] < 0 || icnt[ns] > NumFamily) ierr++;
05039 if (nmax < icnt[ns]) nmax = icnt[ns];
05040 }
05041 if (ierr)
05042 error ("there are %d invalid entries", ierr);
05043 if (nmax == 0)
05044 error ("max number of families is 0");
05045 }
05046
05047 puts (" checking \"FamilyPointers\"");
05048 fflush (stdout);
05049 if (cg_array_info (nfp, name, &datatype, &ndim, dims))
05050 error_exit("cg_array_info");
05051 if (ndim != 3 || dims[0] != 32 ||
05052 dims[1] != nmax || dims[2] != NumSteps) {
05053 error ("invalid dimension values");
05054 ierr = 1;
05055 }
05056 if (datatype != Character) {
05057 error ("data type not character");
05058 ierr = 1;
05059 }
05060 if (NumSteps > 0 && nmax > 0 && !ierr) {
05061 desc = (char *) malloc (32 * nmax * NumSteps * sizeof(char));
05062 if (NULL == desc) {
05063 fprintf (stderr, "malloc failed for family pointers\n");
05064 exit (1);
05065 }
05066 if (cg_array_read (nfp, desc)) error_exit("cg_array_read");
05067 for (ierr = 0, n = 0, ns = 0; ns < NumSteps; ns++) {
05068 for (nd = 0; nd < icnt[ns]; nd++) {
05069 strncpy (name, &desc[n + 32 * nd], 32);
05070 name[32] = 0;
05071 p = name + strlen(name);
05072 while (--p >= name && isspace(*p))
05073 ;
05074 *++p = 0;
05075 for (na = 0; na < NumFamily; na++) {
05076 if (0 == strcmp (name, Family[na])) break;
05077 }
05078 if (na >= NumFamily) ierr++;
05079 }
05080 n += 32 * nmax;
05081 }
05082 free (desc);
05083 if (ierr)
05084 warning (1, "%d unknown families", ierr);
05085 }
05086 if (icnt != NULL) free (icnt);
05087 }
05088
05089
05090
05091 if (nnz && !nzp)
05092 error ("NumberOfZones given but not ZonePointers");
05093 if (!nnz && nzp)
05094 error ("ZonePointers given but not NumberOfZones");
05095 if (nnz && nzp) {
05096 ierr = nmax = 0;
05097 icnt = NULL;
05098 puts (" checking \"NumberOfZones\"");
05099 fflush (stdout);
05100 if (cg_array_info (nnz, name, &datatype, &ndim, dims))
05101 error_exit("cg_array_info");
05102 if (ndim != 1 || dims[0] != NumSteps) {
05103 error ("invalid dimension values");
05104 ierr = 1;
05105 }
05106 if (datatype != Integer) {
05107 error ("data type not integer");
05108 ierr = 1;
05109 }
05110 if (!ierr && NumSteps > 0) {
05111 icnt = (int *) malloc (NumSteps * sizeof(int));
05112 if (icnt == NULL) {
05113 fprintf (stderr, "malloc failed for number of zones\n");
05114 exit (1);
05115 }
05116 if (cg_array_read (nnz, icnt)) error_exit("cg_array_read");
05117 for (ns = 0; ns < NumSteps; ns++) {
05118 if (icnt[ns] < 0 || icnt[ns] > NumZones) ierr++;
05119 if (nmax < icnt[ns]) nmax = icnt[ns];
05120 }
05121 if (ierr)
05122 error ("there are %d invalid entries", ierr);
05123 if (nmax == 0)
05124 error ("max number of zones is 0");
05125 }
05126
05127 printf (" checking \"ZonePointers\"\n");
05128 fflush (stdout);
05129 if (cg_array_info (nzp, name, &datatype, &ndim, dims))
05130 error_exit("cg_array_info");
05131 if (ndim != 3 || dims[0] != 32 ||
05132 dims[1] != nmax || dims[2] != NumSteps) {
05133 error ("invalid dimension values");
05134 ierr = 1;
05135 }
05136 if (datatype != Character) {
05137 error ("data type not character");
05138 ierr = 1;
05139 }
05140 if (NumSteps > 0 && nmax > 0 && !ierr) {
05141 desc = (char *) malloc (32 * nmax * NumSteps * sizeof(char));
05142 if (NULL == desc) {
05143 fprintf (stderr, "malloc failed for zone pointers\n");
05144 exit (1);
05145 }
05146 if (cg_array_read (nzp, desc)) error_exit("cg_array_read");
05147 for (ierr = 0, n = 0, ns = 0; ns < NumSteps; ns++) {
05148 for (nd = 0; nd < icnt[ns]; nd++) {
05149 strncpy (name, &desc[n + 32 * nd], 32);
05150 name[32] = 0;
05151 p = name + strlen(name);
05152 while (--p >= name && isspace(*p))
05153 ;
05154 *++p = 0;
05155 for (na = 0; na < NumZones; na++) {
05156 if (0 == strcmp (name, Zones[na].name)) break;
05157 }
05158 if (na >= NumZones) ierr++;
05159 }
05160 n += 32 * nmax;
05161 }
05162 free (desc);
05163 if (ierr)
05164 warning (1, "%d unknown zones", ierr);
05165 }
05166 if (icnt != NULL) free (icnt);
05167 }
05168
05169 check_user_data (dataclass, punits, 2);
05170 }
05171
05172
05173
05174 static void check_base (void)
05175 {
05176 char basename[33], name[33], *desc;
05177 int n, nz, ierr, nd, nf, eqset[7];
05178 float point[3], vector[3];
05179 SimulationType_t simulation;
05180
05181
05182
05183 if (cg_base_read (cgnsfn, cgnsbase, basename, &CellDim, &PhyDim))
05184 error_exit("cg_base_read");
05185 printf ("\nreading base \"%s\"\n", basename);
05186 fflush (stdout);
05187 if (CellDim < 1) {
05188 error ("Cell Dimension < 1");
05189 return;
05190 }
05191 if (PhyDim < CellDim) {
05192 error ("Physical Dimension < Cell Dimension");
05193 return;
05194 }
05195
05196 if (CellDim < 2 || CellDim > 3 || PhyDim < 2 || PhyDim > 3) {
05197 puts ("INTERNAL:can't handle CellDim and/or Phydim < 2 or > 3");
05198 return;
05199 }
05200
05201
05202
05203 for (nz = 0; nz < NumZones; nz++) {
05204 if (Zones[nz].nsets) {
05205 for (n = 0; n < Zones[nz].nsets; n++) {
05206 if (Zones[nz].sets[n].elements != NULL)
05207 free (Zones[nz].sets[n].elements);
05208 if (Zones[nz].sets[n].parent != NULL)
05209 free (Zones[nz].sets[n].parent);
05210 }
05211 free (Zones[nz].sets);
05212 }
05213 if (Zones[nz].faces)
05214 HashDestroy (Zones[nz].faces, free);
05215 if (Zones[nz].nextnodes)
05216 free (Zones[nz].extnodes);
05217 }
05218
05219 if (cg_nzones (cgnsfn, cgnsbase, &NumZones)) error_exit("cg_nzones");
05220 if (NumZones > MaxZones) {
05221 if (MaxZones)
05222 Zones = (ZONE *) realloc (Zones, NumZones * sizeof(ZONE));
05223 else
05224 Zones = (ZONE *) malloc (NumZones * sizeof(ZONE));
05225 if (NULL == Zones) {
05226 fprintf (stderr, "malloc failed for zones\n");
05227 exit (1);
05228 }
05229 MaxZones = NumZones;
05230 }
05231
05232 for (nz = 0; nz < NumZones; nz++)
05233 read_zone (nz);
05234 cgnszone = 0;
05235
05236
05237
05238 if (cg_nfamilies (cgnsfn, cgnsbase, &NumFamily))
05239 error_exit("cg_nfamilies");
05240 if (NumFamily) {
05241 puts ("reading families");
05242 fflush (stdout);
05243 create_names (NumFamily, &MaxFamily, &Family);
05244 for (nf = 0; nf < NumFamily; nf++) {
05245 if (cg_family_read (cgnsfn, cgnsbase, nf + 1, name, &n, &nd))
05246 error_exit("cg_family_read");
05247 strcpy (Family[nf], name);
05248 }
05249 }
05250
05251
05252
05253 printf ("\nchecking base \"%s\"\n", basename);
05254 if (verbose)
05255 printf (" Cell Dimension=%d\n Physical Dimension=%d\n",
05256 CellDim, PhyDim);
05257 fflush (stdout);
05258
05259 go_absolute (NULL);
05260
05261
05262
05263 if (verbose > 1) {
05264 if (cg_ndescriptors (&nd)) error_exit("cg_ndescriptors");
05265 for (n = 1; n <= nd; n++) {
05266 if (cg_descriptor_read (n, name, &desc))
05267 error_exit("cg_descriptor_read");
05268 if (desc != NULL) {
05269 printf (" Descriptor %s:\n%s\n", name, desc);
05270 cg_free (desc);
05271 }
05272 }
05273 }
05274
05275
05276
05277 ierr = cg_simulation_type_read (cgnsfn, cgnsbase, &simulation);
05278 if (ierr && ierr != CG_NODE_NOT_FOUND)
05279 error_exit("cg_simulation_type_read");
05280 if (ierr == CG_OK && verbose)
05281 printf (" Simulation Type=%s\n", cg_SimulationTypeName(simulation));
05282
05283
05284
05285 BaseClass = read_dataclass ();
05286 pBaseUnits = read_units (BaseUnits);
05287 if (verbose) {
05288 if (BaseClass >= 0) print_dataclass (BaseClass, 2);
05289 if (pBaseUnits) print_units (pBaseUnits, 2);
05290 }
05291
05292
05293
05294 ierr = cg_state_read (&desc);
05295 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_state_read");
05296 if (ierr == CG_OK) {
05297 puts ("checking reference state");
05298 if (desc != NULL) {
05299 if (verbose > 1)
05300 printf (" Descriptor:%s\n", desc);
05301 cg_free (desc);
05302 }
05303 fflush (stdout);
05304 go_absolute ("ReferenceState_t", 1, NULL);
05305 check_arrays (BaseClass, pBaseUnits, 1, 0, 2);
05306 }
05307
05308
05309
05310 go_absolute (NULL);
05311 ierr = cg_equationset_read (&eqset[0], &eqset[1], &eqset[2],
05312 &eqset[3], &eqset[4], &eqset[5], &eqset[6]);
05313 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_equationset_read");
05314 if (ierr == CG_OK) {
05315 puts ("checking equation set");
05316 fflush (stdout);
05317 check_equation_set (eqset, BaseClass, pBaseUnits, 2);
05318 }
05319
05320
05321
05322 for (nf = 1; nf <= NumFamily; nf++)
05323 check_family (nf);
05324
05325
05326
05327 ierr = cg_axisym_read (cgnsfn, cgnsbase, point, vector);
05328 if (ierr && ierr != CG_NODE_NOT_FOUND) error_exit("cg_axisym_read");
05329 if (ierr == CG_OK) {
05330 if (PhyDim != 2)
05331 error ("axisymmetry is only valid for physical dimension of 2");
05332 else {
05333 puts ("checking axisymmetry");
05334 fflush (stdout);
05335 check_axisymmetry (point, vector);
05336 }
05337 }
05338
05339
05340
05341 go_absolute (NULL);
05342 ierr = cg_rotating_read (vector, point);
05343 if (ierr && ierr != CG_NODE_NOT_FOUND)
05344 error_exit("cg_rotating_read");
05345 if (ierr == CG_OK) {
05346 puts ("checking rotating coordinates");
05347 fflush (stdout);
05348 check_rotating (point, vector, BaseClass, pBaseUnits, 2);
05349 }
05350
05351
05352
05353 ierr = cg_gravity_read (cgnsfn, cgnsbase, vector);
05354 if (ierr && ierr != CG_NODE_NOT_FOUND)
05355 error_exit("cg_gravity_read");
05356 if (ierr == CG_OK) {
05357 puts ("checking gravity");
05358 fflush (stdout);
05359 check_gravity (vector);
05360 }
05361
05362
05363
05364 BaseIter = cg_biter_read (cgnsfn, cgnsbase, name, &NumSteps);
05365 if (BaseIter && BaseIter != CG_NODE_NOT_FOUND)
05366 error_exit("cg_biter_read");
05367 if (BaseIter == CG_OK) {
05368 printf ("checking base iterative data \"%s\"\n", name);
05369 fflush (stdout);
05370 check_base_iter ();
05371 }
05372 else
05373 NumSteps = 0;
05374
05375
05376
05377 go_absolute (NULL);
05378 ierr = cg_convergence_read (&nd, &desc);
05379 if (ierr && ierr != CG_NODE_NOT_FOUND)
05380 error_exit("cg_convergence_read");
05381 if (ierr == CG_OK && nd) {
05382 puts ("checking global convergence history");
05383 fflush (stdout);
05384 go_absolute ("ConvergenceHistory_t", 1, NULL);
05385 check_convergence (nd, desc, BaseClass, pBaseUnits, 2);
05386 if (desc != NULL) cg_free (desc);
05387 }
05388
05389
05390
05391 go_absolute (NULL);
05392 check_integral (BaseClass, pBaseUnits, 0);
05393
05394
05395
05396 go_absolute (NULL);
05397 check_user_data (BaseClass, pBaseUnits, 0);
05398
05399
05400
05401 if (NumZones == 0) {
05402 warning (1, "no zones defined");
05403 return;
05404 }
05405
05406 for (cgnszone = 1; cgnszone <= NumZones; cgnszone++)
05407 check_zone ();
05408 }
05409
05410
05411
05412 int main (int argc, char *argv[])
05413 {
05414 char *cgnsfile;
05415 int n, nbases, update = 0;
05416 float file_version;
05417
05418 if (argc < 2)
05419 print_usage (usgmsg, NULL);
05420
05421 while ((n = getargs (argc, argv, options)) > 0) {
05422 switch (n) {
05423 case 'v':
05424 verbose = 1;
05425 break;
05426 case 'V':
05427 verbose = 2;
05428 break;
05429 case 'u':
05430 case 'U':
05431 update = n;
05432 break;
05433 case 'w':
05434 dowarn = atoi (argarg);
05435 break;
05436 case 'e':
05437 doerr = 0;
05438 break;
05439 }
05440 }
05441
05442 if (argind == argc)
05443 print_usage (usgmsg, "CGNSfile not given");
05444 cgnsfile = argv[argind++];
05445
05446
05447
05448 if (update) {
05449 char *newfile = argind < argc ? argv[argind] : NULL;
05450 cgnsfile = update_version (cgnsfile, newfile);
05451 if (update == 'U')
05452 exit (0);
05453 }
05454
05455 printf ("reading CGNS file %s\n", cgnsfile);
05456 fflush (stdout);
05457 if (cg_open (cgnsfile, CG_MODE_READ, &cgnsfn)) error_exit("cg_open");
05458
05459
05460
05461 if (cg_version (cgnsfn, &file_version)) error_exit("cg_version");
05462 FileVersion = (int)(1000.0 * file_version + 0.5);
05463 if (LibraryVersion < FileVersion)
05464 warning (1, "CGNS file version is more recent than library version");
05465
05466
05467
05468 if (cg_nbases (cgnsfn, &nbases)) error_exit("cg_nbases");
05469 if (nbases < 1) warning (1, "no bases defined in CGNS file");
05470 for (cgnsbase = 1; cgnsbase <= nbases; cgnsbase++)
05471 check_base ();
05472
05473
05474
05475 if (cg_close (cgnsfn)) error_exit("cg_close");
05476 puts ("\nchecking complete");
05477 if (totwarn) printf ("%d warnings (%d shown)\n", totwarn, nwarn);
05478 if (nerr) printf ("%d errors\n", nerr);
05479 return 0;
05480 }
05481