1 #include "exodusII.h"
2 #include <stdio.h>
3 #include <stdlib.h> /* for malloc(), free() */
4 
5 #define EX_TEST_FILENAME "edgeFace.exo"
6 
7 #define EXCHECK(funcall,errmsg)\
8   if ( (funcall) < 0 ) \
9     { \
10       fprintf( stderr, errmsg ); \
11       return 1; \
12     }
13 
14 #define EXCHKPI(funcall,errmsg,sucmsg,ival)\
15   if ( (funcall) < 0 ) \
16     { \
17       fprintf( stderr, errmsg ); \
18       return 1; \
19     } else { \
20       fprintf( stdout, sucmsg, ival ); \
21     }
22 
23 int obj_types[] = {
24   EX_EDGE_BLOCK,
25   EX_FACE_BLOCK,
26   EX_ELEM_BLOCK,
27   EX_NODE_SET,
28   EX_EDGE_SET,
29   EX_FACE_SET,
30   EX_SIDE_SET,
31   EX_ELEM_SET,
32   EX_NODE_MAP,
33   EX_EDGE_MAP,
34   EX_FACE_MAP,
35   EX_ELEM_MAP
36 };
37 
38 int obj_sizes[] = {
39   EX_INQ_EDGE_BLK,
40   EX_INQ_FACE_BLK,
41   EX_INQ_ELEM_BLK,
42   EX_INQ_NODE_SETS,
43   EX_INQ_EDGE_SETS,
44   EX_INQ_FACE_SETS,
45   EX_INQ_SIDE_SETS,
46   EX_INQ_ELEM_SETS,
47   EX_INQ_NODE_MAP,
48   EX_INQ_EDGE_MAP,
49   EX_INQ_FACE_MAP,
50   EX_INQ_ELEM_MAP,
51 };
52 
53 const char* obj_typenames[] = {
54   "   Edge block",
55   "   Face block",
56   "Element block",
57   "    Node set",
58   "    Edge set",
59   "    Face set",
60   "    Side set",
61   " Element set",
62   "    Node map",
63   "    Edge map",
64   "    Face map",
65   " Element map"
66 };
67 
68 const char* obj_typestr[] = {
69   "L",
70   "F",
71   "E",
72   "M",
73   "D",
74   "A",
75   "S",
76   "T",
77   0, /* maps have no result variables */
78   0,
79   0,
80   0,
81 };
82 
83 int obj_sizeinq[] = {
84   EX_INQ_EDGE,
85   EX_INQ_FACE,
86   EX_INQ_ELEM,
87   EX_INQ_NS_NODE_LEN,
88   EX_INQ_ES_LEN,
89   EX_INQ_FS_LEN,
90   EX_INQ_SS_ELEM_LEN,
91   EX_INQ_ELS_LEN,
92   -1,
93   -1,
94   -1,
95   -1
96 };
97 
98 #define OBJECT_IS_BLOCK(i) ((i>=0)&&(i<3))
99 #define OBJECT_IS_SET(i) ((i>2)&&(i<8))
100 
cReadEdgeFace(int argc,char * argv[])101 int cReadEdgeFace( int argc, char* argv[] )
102 {
103   int exoid;
104   int appWordSize = 8;
105   int diskWordSize = 8;
106   float exoVersion;
107   int itmp[5];
108   int* ids;
109   int nids;
110   int obj;
111   int i, j;
112   int num_timesteps;
113   int ti;
114   char** obj_names;
115   char** var_names;
116   int have_var_names;
117   int num_vars; /* number of variables per object */
118   int num_entries; /* number of values per variable per object */
119   double* entry_vals; /* variable values for each entry of an object */
120   ex_init_params modelParams;
121 
122   (void)argc;
123   (void)argv;
124 
125   exoid = ex_open( EX_TEST_FILENAME, EX_READ, &appWordSize, &diskWordSize, &exoVersion );
126   if ( exoid <= 0 )
127     {
128     fprintf( stderr, "Unable to open \"%s\" for reading.\n", EX_TEST_FILENAME );
129     return 1;
130     }
131 
132   EXCHECK( ex_get_init_ext( exoid, &modelParams ),
133     "Unable to read database parameters.\n" );
134 
135   fprintf( stdout,
136     "Title: <%s>\n"
137     "Dimension: %d\n"
138     "Nodes: %d\n"
139     "Edges: %d\n"
140     "Faces: %d\n"
141     "Elements: %d\n"
142     "Edge Blocks: %d\n"
143     "Face Blocks: %d\n"
144     "Element Blocks: %d\n"
145     "Node Sets: %d\n"
146     "Edge Sets: %d\n"
147     "Face Sets: %d\n"
148     "Side Sets: %d\n"
149     "Element Sets: %d\n"
150     "Node Maps: %d\n"
151     "Edge Maps: %d\n"
152     "Face Maps: %d\n"
153     "Element Maps: %d\n",
154     modelParams.title, modelParams.num_dim,
155     modelParams.num_nodes, modelParams.num_edge, modelParams.num_face, modelParams.num_elem,
156     modelParams.num_edge_blk, modelParams.num_face_blk, modelParams.num_elem_blk,
157     modelParams.num_node_sets, modelParams.num_edge_sets, modelParams.num_face_sets,
158     modelParams.num_side_sets, modelParams.num_elem_sets,
159     modelParams.num_node_maps, modelParams.num_edge_maps, modelParams.num_face_maps,
160     modelParams.num_elem_maps );
161 
162   /* *** NEW API *** */
163   EXCHKPI( ex_inquire( exoid, EX_INQ_EDGE,       itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_EDGE : %d\n", itmp[0] );
164   EXCHKPI( ex_inquire( exoid, EX_INQ_EDGE_BLK,   itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_EDGE_BLK : %d\n", itmp[0] );
165   EXCHKPI( ex_inquire( exoid, EX_INQ_EDGE_SETS,  itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_EDGE_SETS : %d\n", itmp[0] );
166   EXCHKPI( ex_inquire( exoid, EX_INQ_ES_LEN,     itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_ES_LEN : %d\n", itmp[0] );
167   EXCHKPI( ex_inquire( exoid, EX_INQ_ES_DF_LEN,  itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_ES_DF_LEN : %d\n", itmp[0] );
168   EXCHKPI( ex_inquire( exoid, EX_INQ_EDGE_PROP,  itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_EDGE_PROP : %d\n", itmp[0] );
169   EXCHKPI( ex_inquire( exoid, EX_INQ_ES_PROP,    itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_ES_PROP : %d\n", itmp[0] );
170   EXCHKPI( ex_inquire( exoid, EX_INQ_FACE,       itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_FACE : %d\n", itmp[0] );
171   EXCHKPI( ex_inquire( exoid, EX_INQ_FACE_BLK,   itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_FACE_BLK : %d\n", itmp[0] );
172   EXCHKPI( ex_inquire( exoid, EX_INQ_FACE_SETS,  itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_FACE_SETS : %d\n", itmp[0] );
173   EXCHKPI( ex_inquire( exoid, EX_INQ_FS_LEN,     itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_FS_LEN : %d\n", itmp[0] );
174   EXCHKPI( ex_inquire( exoid, EX_INQ_FS_DF_LEN,  itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_FS_DF_LEN : %d\n", itmp[0] );
175   EXCHKPI( ex_inquire( exoid, EX_INQ_FACE_PROP,  itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_FACE_PROP : %d\n", itmp[0] );
176   EXCHKPI( ex_inquire( exoid, EX_INQ_FS_PROP,    itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_FS_PROP : %d\n", itmp[0] );
177   EXCHKPI( ex_inquire( exoid, EX_INQ_ELEM_SETS,  itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_ELEM_SETS : %d\n", itmp[0] );
178   EXCHKPI( ex_inquire( exoid, EX_INQ_ELS_LEN,    itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_ELS_LEN : %d\n", itmp[0] );
179   EXCHKPI( ex_inquire( exoid, EX_INQ_ELS_DF_LEN, itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_ELS_DF_LEN : %d\n", itmp[0] );
180   EXCHKPI( ex_inquire( exoid, EX_INQ_ELS_PROP,   itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_ELS_PROP : %d\n", itmp[0] );
181   EXCHKPI( ex_inquire( exoid, EX_INQ_TIME,       itmp, 0, 0 ), "Inquire failed.\n", "EX_INQ_TIME     : %d\n", itmp[0] );
182   num_timesteps = itmp[0];
183 
184   /* *** NEW API *** */
185   for ( i = 0; i < (int)(sizeof(obj_types)/sizeof(obj_types[0])); ++i ) {
186     int* truth_tab = 0;
187     have_var_names = 0;
188 
189     EXCHECK( ex_inquire( exoid, obj_sizes[i], &nids, 0, 0 ), "Object ID list size could not be determined.\n" );
190 
191     if ( ! nids ) {
192       fprintf( stdout, "=== %ss: none\n\n", obj_typenames[i] );
193       continue;
194     } else {
195       fprintf( stdout, "=== %ss: %d\n", obj_typenames[i], nids );
196     }
197 
198     ids = (int*) malloc( nids * sizeof(int) );
199     obj_names = (char**) malloc( nids * sizeof(char*) );
200     for ( obj = 0; obj < nids; ++obj )
201       obj_names[obj] = (char*) malloc( (MAX_STR_LENGTH + 1) * sizeof(char) );
202 
203     EXCHECK( ex_get_ids( exoid, obj_types[i], ids ), "Could not read object ids.\n" );
204     EXCHECK( ex_get_names( exoid, obj_types[i], obj_names ), "Could not read object ids.\n" );
205 
206     if ( (OBJECT_IS_BLOCK(i)) || (OBJECT_IS_SET(i)) ) {
207       int* tp;
208       EXCHECK( ex_get_var_param( exoid, obj_typestr[i], &num_vars ), "Could not read number of variables.\n" );
209 
210       if ( num_vars && num_timesteps > 0 ) {
211         truth_tab = (int*) malloc( num_vars * nids * sizeof(int) );
212         EXCHECK( ex_get_var_tab( exoid, obj_typestr[i], nids, num_vars, truth_tab ), "Could not read truth table.\n" );
213         tp = truth_tab;
214         fprintf( stdout, "Truth:" );
215         for ( obj = 0; obj < nids; ++obj ) {
216           for ( j = 0; j < num_vars; ++j, ++tp ) {
217             fprintf( stdout, " %d", *tp );
218           }
219           fprintf( stdout, "\n      " );
220         }
221         fprintf( stdout, "\n" );
222 
223         var_names = (char**) malloc( num_vars * sizeof(char*) );
224         for ( j = 0; j < num_vars; ++j )
225           var_names[j] = (char*) malloc( (MAX_STR_LENGTH + 1) * sizeof(char) );
226 
227         EXCHECK( ex_get_var_names( exoid, obj_typestr[i], num_vars, var_names ), "Could not read variable names.\n" );
228         have_var_names = 1;
229       }
230     }
231 
232     if ( ! have_var_names )
233       var_names = 0;
234 
235     for ( obj = 0; obj < nids; ++obj ) {
236       if ( obj_names[obj] )
237         fprintf( stdout, "%s %3d (%s): ", obj_typenames[i], ids[obj], obj_names[obj] );
238       else
239         fprintf( stdout, "%s %3d: ", obj_typenames[i], ids[obj] );
240 
241       if ( OBJECT_IS_BLOCK(i) ) {
242         int* nconn;
243         int* econn;
244         int* fconn;
245         int ele;
246         int ctr;
247         int num_attrs;
248         if ( obj_types[i] == EX_ELEM_BLOCK ) {
249           EXCHECK( ex_get_block( exoid, obj_types[i], ids[obj], 0, itmp, itmp+1, itmp+2, itmp+3, &num_attrs ),
250             "Could not read block params.\n" );
251           fprintf( stdout, "Entries: %3d Nodes/entry: %d Edges/entry: %d Faces/entry: %d Attributes: %d",
252             itmp[0], itmp[1], itmp[2], itmp[3], num_attrs );
253         } else {
254           EXCHECK( ex_get_block( exoid, obj_types[i], ids[obj], 0, itmp, itmp+1, 0, 0, &num_attrs ),
255             "Could not read block params.\n" );
256           fprintf( stdout, "Entries: %3d Nodes/entry: %d Attributes: %d", itmp[0], itmp[1], num_attrs );
257           itmp[2] = itmp[3] = 0;
258         }
259         fprintf( stdout, "\n   " );
260         num_entries = itmp[0];
261         nconn = itmp[1] ? (int*) malloc( itmp[1] * num_entries * sizeof(int) ) : 0;
262         econn = itmp[2] ? (int*) malloc( itmp[2] * num_entries * sizeof(int) ) : 0;
263         fconn = itmp[3] ? (int*) malloc( itmp[3] * num_entries * sizeof(int) ) : 0;
264         EXCHECK( ex_get_conn( exoid, obj_types[i], ids[obj], nconn, econn, fconn ), "Could not read connectivity.\n" );
265         for ( ele = 0; ele < num_entries; ++ele ) {
266           for ( ctr = 0; ctr < itmp[1]; ++ctr ) {
267             fprintf( stdout, " %2d", nconn[ele*itmp[1] + ctr] );
268           }
269           if ( itmp[2] ) {
270             fprintf( stdout, "  ++" );
271             for ( ctr = 0; ctr < itmp[2]; ++ctr ) {
272               fprintf( stdout, " %2d", econn[ele*itmp[2] + ctr] );
273             }
274           }
275           if ( itmp[3] ) {
276             fprintf( stdout, "  ++" );
277             for ( ctr = 0; ctr < itmp[3]; ++ctr ) {
278               fprintf( stdout, " %2d", fconn[ele*itmp[3] + ctr] );
279             }
280           }
281           fprintf( stdout, "\n   " );
282         }
283         if ( nconn ) free( nconn );
284         if ( econn ) free( econn );
285         if ( fconn ) free( fconn );
286 
287         if ( num_attrs ) {
288           char** attr_names;
289           double* attr;
290           attr = (double*) malloc( num_entries * num_attrs * sizeof(double) );
291           attr_names = (char**) malloc( num_attrs * sizeof(char*) );
292           for ( j = 0; j < num_attrs; ++j )
293             attr_names[j] = (char*) malloc( (MAX_STR_LENGTH + 1) * sizeof(char) );
294 
295           EXCHECK( ex_get_attr_names( exoid, obj_types[i], ids[obj], attr_names ), "Could not read attributes names.\n" );
296           EXCHECK( ex_get_attr( exoid, obj_types[i], ids[obj], attr ), "Could not read attribute values.\n" );
297 
298           fprintf( stdout, "\n      Attributes:\n      ID " );
299           for ( j = 0; j < num_attrs; ++j )
300             fprintf( stdout, " %s", attr_names[j] );
301           fprintf( stdout, "\n" );
302           for ( j = 0; j < num_entries; ++j ) {
303             int k;
304             fprintf( stdout, "      %2d ", j + 1 );
305             for ( k = 0; k < num_attrs; ++k ) {
306               fprintf( stdout, " %4.1f", attr[ j * num_attrs + k ] );
307             }
308             fprintf( stdout, "\n" );
309           }
310 
311           for ( j = 0; j < num_attrs; ++j )
312             free( attr_names[j] );
313           free( attr_names );
314           free( attr );
315         }
316 
317       } else if ( OBJECT_IS_SET(i) ) {
318         int num_df;
319         int* set_entry;
320         int* set_extra;
321         double* set_df;
322         EXCHECK( ex_get_set_param( exoid, obj_types[i], ids[obj], &num_entries, &num_df ), "Could not read set parameters.\n" );
323 
324         set_entry = (int*) malloc( num_entries * sizeof(int) );
325         set_extra = ( obj_types[i] != EX_NODE_SET && obj_types[i] != EX_ELEM_SET ) ?  (int*) malloc( num_entries * sizeof(int) ) : 0;
326         EXCHECK( ex_get_set( exoid, obj_types[i], ids[obj], set_entry, set_extra ), "Could not read set.\n" );
327         fprintf( stdout, "Entries: %3d Distribution factors: %3d\n", num_entries, num_df );
328         if ( set_extra ) {
329           for ( j = 0; j < num_entries; ++j )
330             fprintf( stdout, "      %2d %2d\n", set_entry[j], set_extra[j] );
331         } else {
332           for ( j = 0; j < num_entries; ++j )
333             fprintf( stdout, "      %2d\n", set_entry[j] );
334         }
335         free( set_entry );
336         if ( set_extra )
337           free( set_extra );
338 
339         set_df = num_df ? (double*) malloc( num_df * sizeof(double) ) : 0;
340         if ( set_df ) {
341           EXCHECK( ex_get_set_dist_fact( exoid, obj_types[i], ids[obj], set_df ), "Could not read set distribution factors.\n" );
342           fprintf( stdout, "\n    Distribution factors:\n" );
343           for ( j = 0; j < num_df; ++j )
344             fprintf( stdout, "      %4.1f\n", set_df[j] );
345           free( set_df );
346         }
347 
348 
349       } else { /* object is map */
350         int* map;
351         switch (obj_types[i]) {
352         case EX_NODE_MAP:
353           num_entries = modelParams.num_nodes;
354           break;
355         case EX_EDGE_MAP:
356           num_entries = modelParams.num_edge;
357           break;
358         case EX_FACE_MAP:
359           num_entries = modelParams.num_face;
360           break;
361         case EX_ELEM_MAP:
362           num_entries = modelParams.num_elem;
363           break;
364         }
365         if ( num_entries ) {
366           fprintf( stdout, "Entries: %3d\n                :", num_entries );
367           map = (int*) malloc( num_entries * sizeof(int) );
368           EXCHECK( ex_get_num_map( exoid, obj_types[i], ids[obj], map ), "Could not read map.\n" );
369           for ( j = 0; j < num_entries; ++j ) {
370             fprintf( stdout, " %d", map[j] );
371           }
372         } else {
373           fprintf( stdout, "Entries: none" );
374         }
375       }
376       fprintf( stdout, "\n" );
377 
378       /* Read results variables */
379       if ( ((OBJECT_IS_BLOCK(i)) || (OBJECT_IS_SET(i))) && num_vars && num_timesteps > 0 ) {
380         /* Print out all the time values to exercise get_var */
381         entry_vals = (double*) malloc( num_entries * sizeof(double) );
382         for ( j = 0; j < num_vars; ++j ) {
383           int k;
384           if ( ! truth_tab[num_vars * obj + j] )
385             continue;
386 
387           fprintf( stdout, "      Variable: %s", var_names[j] );
388           for ( ti = 1; ti <= num_timesteps; ++ti ) {
389             EXCHECK( ex_get_var( exoid, ti, obj_types[i], 1 + j, ids[obj], num_entries, entry_vals ),
390               "Could not read variable values.\n" );
391 
392             fprintf( stdout, "\n       @t%d ", ti );
393             for ( k = 0; k < num_entries; ++k ) {
394               fprintf( stdout, " %4.1f", entry_vals[k] );
395             }
396           }
397           fprintf( stdout, "\n" );
398         }
399         fprintf( stdout, "\n" );
400         free( entry_vals );
401       }
402     }
403 
404     if ( ((OBJECT_IS_BLOCK(i)) || (OBJECT_IS_SET(i))) && num_vars && num_timesteps > 0 ) {
405       /* Print out one element's time values to exercise get_var_time */
406       entry_vals = (double*) malloc( num_timesteps * sizeof( double ) );
407       EXCHECK( ex_inquire( exoid, obj_sizeinq[i], itmp, 0, 0 ), "Inquire failed.\n" );
408       itmp[1] = 11;
409       while ( itmp[1] > itmp[0] ) itmp[1] /= 2;
410       for ( j = 0; j < num_vars; ++j ) {
411         /* FIXME: This works for the dataset created by CreateEdgeFace, but not for any dataset in general since
412          * NULL truth table entries may mean the referenced elements don't have variable values.
413          */
414         EXCHECK( ex_get_var_time( exoid, obj_types[i], j + 1, itmp[1], 1, num_timesteps, entry_vals ), "Could not read variable over time.\n" );
415         fprintf( stdout, "    Variable over time: %s  Entry: %3d ", var_names[j], itmp[1] );
416         for ( ti = 1; ti <= num_timesteps; ++ti )
417           fprintf( stdout, " @t%d: %4.1f", ti, entry_vals[ti-1] );
418         fprintf( stdout, "\n" );
419       }
420       free( entry_vals );
421     }
422 
423     if ( var_names ) {
424       for ( j = 0; j < num_vars; ++j )
425         free( var_names[j] );
426       free( var_names );
427     }
428     if ( truth_tab )
429       free( truth_tab );
430     free( ids );
431 
432     for ( obj = 0; obj < nids; ++obj )
433       free( obj_names[obj] );
434     free( obj_names );
435 
436     fprintf( stdout, "\n" );
437   }
438 
439   EXCHECK( ex_close( exoid ),
440     "Unable to close database.\n" );
441 
442   return 0;
443 }
444 
445 #ifndef EXO_CTEST
main(int argc,char * argv[])446 int main( int argc, char* argv[] )
447 {
448   return cReadEdgeFace(argc, argv);
449 }
450 #endif /* EXO_CTEST */
451