1 /*
2  * Copyright (c) 2006 Sandia Corporation. Under the terms of Contract
3  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Governement
4  * retains certain rights in this software.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *
13  *     * Redistributions in binary form must reproduce the above
14  *       copyright notice, this list of conditions and the following
15  *       disclaimer in the documentation and/or other materials provided
16  *       with the distribution.
17  *
18  *     * Neither the name of Sandia Corporation nor the names of its
19  *       contributors may be used to endorse or promote products derived
20  *       from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  */
35 /*****************************************************************************
36 *
37 * expvp - ex_put_all_var_param_ext
38 *
39 * entry conditions -
40 *   input parameters:
41 *       int                  exoid    exodus file id
42 *       const ex_var_params* vp       pointer to variable parameter info
43 *
44 * exit conditions -
45 *
46 *****************************************************************************/
47 
48 #include <stdlib.h>
49 #include "exodusII.h"
50 #include "exodusII_int.h"
51 
52 #include <ctype.h>
53 static void *safe_free(void *array);
54 static int define_dimension(int exoid, const char *DIMENSION, int count, const char *label, int *dimid);
55 static int define_variable_name_variable(int exoid, const char *VARIABLE, int dimension,
56                                          const char *label);
57 static int *get_status_array(int exoid, int count, const char *VARIABLE, const char *label);
58 static int put_truth_table(int exoid, int varid, int *table, const char *label);
59 static int define_truth_table(ex_entity_type obj_type, int exoid, int num_ent, int num_var,
60                               int *var_tab, int *status, void_int *ids, const char *label);
61 
62 #define EX_GET_IDS_STATUS(TNAME,NUMVAR,DNAME,DID,DVAL,VIDS,EIDS,VSTAT,VSTATVAL) \
63   if (NUMVAR > 0) {							\
64     status = ex_get_dimension(exoid, DNAME, TNAME "s", &DVAL, &DID, routine); \
65     if (status != NC_NOERR)						\
66       goto error_ret;							\
67 									\
68     /* get element block IDs */						\
69     if (!(VIDS = malloc(DVAL*sizeof(int64_t)))) {				\
70       exerrval = EX_MEMFAIL;						\
71       sprintf(errmsg,							\
72               "Error: failed to allocate memory for " TNAME " id array for file id %d", \
73               exoid);							\
74       ex_err("ex_put_all_var_param_ext",errmsg,exerrval);		\
75       goto error_ret;							\
76     }									\
77     ex_get_ids (exoid, EIDS, VIDS);					\
78 									\
79     /* Get element block status array for later use (allocates memory) */ \
80     VSTATVAL = get_status_array(exoid, DVAL, VSTAT, TNAME);		\
81     if (VSTATVAL == NULL) {						\
82       goto error_ret;							\
83     }									\
84   }
85 
86 /*!
87  * writes the number of global, nodal, element, nodeset, and sideset variables
88  * that will be written to the database
89  * \param      exoid    exodus file id
90  * \param      *vp       pointer to variable parameter info
91  */
92 
ex_put_all_var_param_ext(int exoid,const ex_var_params * vp)93 int ex_put_all_var_param_ext ( int   exoid,
94                                const ex_var_params* vp )
95 {
96   int in_define = 0;
97   int status;
98   int temp;
99   int time_dim, num_nod_dim, dimid;
100   size_t num_elem_blk, num_edge_blk, num_face_blk;
101   size_t num_nset, num_eset, num_fset, num_sset, num_elset;
102   int numelblkdim, numelvardim, numedvardim, numedblkdim,
103     numfavardim, numfablkdim,  numnsetdim,  nsetvardim,
104     numesetdim,  esetvardim,   numfsetdim,  fsetvardim,
105     numssetdim,  ssetvardim,  numelsetdim, elsetvardim;
106   int i;
107 
108   int edblk_varid, fablk_varid, eblk_varid, nset_varid,
109     eset_varid, fset_varid, sset_varid, elset_varid, varid;
110 
111   void_int* eblk_ids = 0;
112   void_int* edblk_ids = 0;
113   void_int* fablk_ids = 0;
114   void_int* nset_ids = 0;
115   void_int* eset_ids = 0;
116   void_int* fset_ids = 0;
117   void_int* sset_ids = 0;
118   void_int* elset_ids = 0;
119 
120   int* eblk_stat = 0;
121   int* edblk_stat = 0;
122   int* fablk_stat = 0;
123   int* nset_stat = 0;
124   int* eset_stat = 0;
125   int* fset_stat = 0;
126   int* sset_stat = 0;
127   int* elset_stat = 0;
128 
129   int dims[3];
130   char errmsg[MAX_ERR_LENGTH];
131   const char* routine = "ex_put_all_var_param_ext";
132 
133   exerrval = 0; /* clear error code */
134 
135   /* inquire previously defined dimensions  */
136 
137   if ((status = nc_inq_dimid(exoid, DIM_TIME, &time_dim)) != NC_NOERR) {
138     exerrval = status;
139     sprintf(errmsg,
140             "Error: failed to locate time dimension in file id %d", exoid);
141     ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
142     goto error_ret;
143   }
144 
145   if ((status = nc_inq_dimid (exoid, DIM_NUM_NODES, &num_nod_dim)) != NC_NOERR) {
146     num_nod_dim = -1; /* There is probably no nodes on this file */
147   }
148 
149   /* Check this now so we can use it later without checking for errors */
150   if ((status = nc_inq_dimid(exoid, DIM_STR_NAME, &temp)) != NC_NOERR) {
151     exerrval = status;
152     sprintf(errmsg,
153             "Error: failed to get string length in file id %d",exoid);
154     ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
155     goto error_ret;
156   }
157 
158   EX_GET_IDS_STATUS(   "edge block",vp->num_edge, DIM_NUM_ED_BLK,numedblkdim,num_edge_blk,edblk_ids,EX_EDGE_BLOCK,VAR_STAT_ED_BLK,edblk_stat);
159   EX_GET_IDS_STATUS(   "face block",vp->num_face, DIM_NUM_FA_BLK,numfablkdim,num_face_blk,fablk_ids,EX_FACE_BLOCK,VAR_STAT_FA_BLK,fablk_stat);
160   EX_GET_IDS_STATUS("element block",vp->num_elem, DIM_NUM_EL_BLK,numelblkdim,num_elem_blk, eblk_ids,EX_ELEM_BLOCK,VAR_STAT_EL_BLK, eblk_stat);
161   EX_GET_IDS_STATUS(     "node set",vp->num_nset, DIM_NUM_NS,    numnsetdim, num_nset,     nset_ids,EX_NODE_SET,  VAR_NS_STAT,     nset_stat);
162   EX_GET_IDS_STATUS(     "edge set",vp->num_eset, DIM_NUM_ES,    numesetdim, num_eset,     eset_ids,EX_EDGE_SET,  VAR_ES_STAT,     eset_stat);
163   EX_GET_IDS_STATUS(     "face set",vp->num_fset, DIM_NUM_FS,    numfsetdim, num_fset,     fset_ids,EX_FACE_SET,  VAR_FS_STAT,     fset_stat);
164   EX_GET_IDS_STATUS(     "side set",vp->num_sset, DIM_NUM_SS,    numssetdim, num_sset,     sset_ids,EX_SIDE_SET,  VAR_SS_STAT,     sset_stat);
165   EX_GET_IDS_STATUS(  "element set",vp->num_elset,DIM_NUM_ELS,   numelsetdim,num_elset,   elset_ids,EX_ELEM_SET,  VAR_ELS_STAT,   elset_stat);
166 
167   /* put file into define mode  */
168   if ((status = nc_redef (exoid)) != NC_NOERR) {
169     exerrval = status;
170     sprintf(errmsg,
171 	    "Error: failed to put file id %d into define mode", exoid);
172     ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
173     goto error_ret;
174   }
175   in_define = 1;
176 
177   /* define dimensions and variables */
178   if (vp->num_glob > 0) {
179     if (define_dimension(exoid, DIM_NUM_GLO_VAR, vp->num_glob, "global", &dimid) != NC_NOERR)
180       goto error_ret;
181 
182     dims[0] = time_dim;
183     dims[1] = dimid;
184     if ((status = nc_def_var (exoid, VAR_GLO_VAR, nc_flt_code(exoid), 2, dims, &varid)) != NC_NOERR) {
185       exerrval = status;
186       sprintf(errmsg,
187 	      "Error: failed to define global variables in file id %d",
188 	      exoid);
189       ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
190       goto error_ret;          /* exit define mode and return */
191     }
192     ex_compress_variable(exoid, varid, 2);
193 
194     /* Now define global variable name variable */
195     if (define_variable_name_variable(exoid, VAR_NAME_GLO_VAR, dimid, "global") != NC_NOERR)
196       goto error_ret;
197   }
198 
199   if (vp->num_node > 0 && num_nod_dim > 0) {
200     /*
201      * There are two ways to store the nodal variables. The old way *
202      * was a blob (#times,#vars,#nodes), but that was exceeding the
203      * netcdf maximum dataset size for large models. The new way is
204      * to store #vars separate datasets each of size (#times,#nodes)
205      *
206      * We want this routine to be capable of storing both formats
207      * based on some external flag.  Since the storage format of the
208      * coordinates have also been changed, we key off of their
209      * storage type to decide which method to use for nodal
210      * variables. If the variable 'coord' is defined, then store old
211      * way; otherwise store new.
212      */
213     if (define_dimension(exoid, DIM_NUM_NOD_VAR, vp->num_node, "nodal", &dimid) != NC_NOERR)
214       goto error_ret;
215 
216     if (ex_large_model(exoid) == 0) { /* Old way */
217       dims[0] = time_dim;
218       dims[1] = dimid;
219       dims[2] = num_nod_dim;
220       if ((status = nc_def_var(exoid, VAR_NOD_VAR,
221 			       nc_flt_code(exoid), 3, dims, &varid)) != NC_NOERR) {
222 	exerrval = status;
223 	sprintf(errmsg,
224 		"Error: failed to define nodal variables in file id %d",
225 		exoid);
226 	ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
227 	goto error_ret;          /* exit define mode and return */
228       }
229     } else { /* Store new way */
230       for (i = 1; i <= vp->num_node; i++) {
231 	dims[0] = time_dim;
232 	dims[1] = num_nod_dim;
233 	if ((status = nc_def_var(exoid, VAR_NOD_VAR_NEW(i),
234 				 nc_flt_code(exoid), 2, dims, &varid)) != NC_NOERR) {
235 	  exerrval = status;
236 	  sprintf(errmsg,
237 		  "Error: failed to define nodal variable %d in file id %d",
238 		  i, exoid);
239 	  ex_err("ex_put_var_param",errmsg,exerrval);
240 	  goto error_ret;          /* exit define mode and return */
241 	}
242 	ex_compress_variable(exoid, varid, 2);
243       }
244     }
245 
246     /* Now define nodal variable name variable */
247     if (define_variable_name_variable(exoid, VAR_NAME_NOD_VAR, dimid, "nodal") != NC_NOERR)
248       goto error_ret;
249   }
250 
251 #define EX_DEFINE_VARS(TID,STNAME,TNAME,NUMVAR,DNAME,DID1,DID2,DVAL,VIDS,VNOV,VTV,VSTATVAL,VTABVAL,VTABVAR) \
252   if (NUMVAR > 0) {							\
253     status = define_dimension(exoid, DNAME, NUMVAR, STNAME, &DID2);	\
254     if (status != NC_NOERR) goto error_ret;				\
255 									\
256     /* Now define STNAME variable name variable */			\
257     if (define_variable_name_variable(exoid, VNOV, DID2, STNAME) != NC_NOERR) \
258       goto error_ret;							\
259 									\
260     if (define_truth_table(TID, exoid, DVAL, NUMVAR, VTABVAL, VSTATVAL, VIDS, TNAME) != NC_NOERR) \
261       goto error_ret;							\
262 									\
263     VSTATVAL = safe_free (VSTATVAL);					\
264     VIDS  = safe_free (VIDS);						\
265 									\
266     /* create a variable array in which to store the STNAME variable truth \
267      * table								\
268      */									\
269 									\
270     dims[0] = DID1;							\
271     dims[1] = DID2;							\
272 									\
273     if ((status = nc_def_var(exoid, VTV, NC_INT, 2, dims, &VTABVAR)) != NC_NOERR) { \
274       exerrval = status;						\
275       sprintf(errmsg,							\
276               "Error: failed to define " STNAME " variable truth table in file id %d", \
277               exoid);							\
278       ex_err("ex_put_all_var_param_ext",errmsg,exerrval);		\
279       goto error_ret;          /* exit define mode and return */	\
280     }									\
281   }
282   EX_DEFINE_VARS(EX_EDGE_BLOCK,   "edge",   "edge block",vp->num_edge, DIM_NUM_EDG_VAR,  numedblkdim,numedvardim,num_edge_blk,edblk_ids,VAR_NAME_EDG_VAR,  VAR_EBLK_TAB, edblk_stat,vp->edge_var_tab,edblk_varid);
283   EX_DEFINE_VARS(EX_FACE_BLOCK,   "face",   "face block",vp->num_face, DIM_NUM_FAC_VAR,  numfablkdim,numfavardim,num_face_blk,fablk_ids,VAR_NAME_FAC_VAR,  VAR_FBLK_TAB, fablk_stat,vp->face_var_tab,fablk_varid);
284   EX_DEFINE_VARS(EX_ELEM_BLOCK,"element","element block",vp->num_elem, DIM_NUM_ELE_VAR,  numelblkdim,numelvardim,num_elem_blk, eblk_ids,VAR_NAME_ELE_VAR,  VAR_ELEM_TAB,  eblk_stat,vp->elem_var_tab,eblk_varid);
285   EX_DEFINE_VARS(EX_NODE_SET,  "nodeset",     "node set",vp->num_nset, DIM_NUM_NSET_VAR, numnsetdim, nsetvardim, num_nset,     nset_ids,VAR_NAME_NSET_VAR, VAR_NSET_TAB,  nset_stat,vp->nset_var_tab, nset_varid);
286   EX_DEFINE_VARS(EX_EDGE_SET,  "edgeset",     "edge set",vp->num_eset, DIM_NUM_ESET_VAR, numesetdim, esetvardim, num_eset,     eset_ids,VAR_NAME_ESET_VAR, VAR_ESET_TAB,  eset_stat,vp->eset_var_tab, eset_varid);
287   EX_DEFINE_VARS(EX_FACE_SET,  "faceset",     "face set",vp->num_fset, DIM_NUM_FSET_VAR, numfsetdim, fsetvardim, num_fset,     fset_ids,VAR_NAME_FSET_VAR, VAR_FSET_TAB,  fset_stat,vp->fset_var_tab, fset_varid);
288   EX_DEFINE_VARS(EX_SIDE_SET,  "sideset",     "side set",vp->num_sset, DIM_NUM_SSET_VAR, numssetdim, ssetvardim, num_sset,     sset_ids,VAR_NAME_SSET_VAR, VAR_SSET_TAB,  sset_stat,vp->sset_var_tab, sset_varid);
289   EX_DEFINE_VARS(EX_ELEM_SET,  "elemset",  "element set",vp->num_elset,DIM_NUM_ELSET_VAR,numelsetdim,elsetvardim,num_elset,   elset_ids,VAR_NAME_ELSET_VAR,VAR_ELSET_TAB,elset_stat,vp->elset_var_tab,elset_varid);
290 
291   /* leave define mode  */
292 
293   in_define = 0;
294   if ((status = nc_enddef (exoid)) != NC_NOERR)
295     {
296       exerrval = status;
297       sprintf(errmsg,
298               "Error: failed to complete definition in file id %d",
299               exoid);
300       ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
301       goto error_ret;
302     }
303 
304   /* write out the variable truth tables */
305   if (vp->num_edge > 0) {
306     if (put_truth_table(exoid, edblk_varid, vp->edge_var_tab, "edge") != NC_NOERR)
307       goto error_ret;
308   }
309 
310   if (vp->num_face > 0) {
311     if (put_truth_table(exoid, fablk_varid, vp->face_var_tab, "face") != NC_NOERR)
312       goto error_ret;
313   }
314 
315   if (vp->num_elem > 0) {
316     if (put_truth_table(exoid, eblk_varid, vp->elem_var_tab, "element") !=  NC_NOERR)
317       goto error_ret;
318   }
319 
320   if (vp->num_nset > 0) {
321     if (put_truth_table(exoid, nset_varid, vp->nset_var_tab, "nodeset") != NC_NOERR)
322       goto error_ret;
323   }
324 
325   if (vp->num_eset > 0) {
326     if (put_truth_table(exoid, eset_varid, vp->eset_var_tab, "edgeset") != NC_NOERR)
327       goto error_ret;
328   }
329 
330   if (vp->num_fset > 0) {
331     if (put_truth_table(exoid, fset_varid, vp->fset_var_tab, "faceset") != NC_NOERR)
332       goto error_ret;
333   }
334 
335   if (vp->num_sset > 0) {
336     if (put_truth_table(exoid, sset_varid, vp->sset_var_tab, "sideset") != NC_NOERR)
337       goto error_ret;
338   }
339 
340   if (vp->num_elset > 0) {
341     if (put_truth_table(exoid, elset_varid, vp->elset_var_tab, "elemset") != NC_NOERR)
342       goto error_ret;
343   }
344 
345   return(EX_NOERR);
346 
347   /* Fatal error: exit definition mode and return */
348  error_ret:
349   if (in_define == 1) {
350     if (nc_enddef (exoid) != NC_NOERR)     /* exit define mode */
351       {
352         sprintf(errmsg,
353                 "Error: failed to complete definition for file id %d",
354                 exoid);
355         ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
356       }
357   }
358   safe_free(eblk_ids);
359   safe_free(edblk_ids);
360   safe_free(fablk_ids);
361   safe_free(nset_ids);
362   safe_free(eset_ids);
363   safe_free(fset_ids);
364   safe_free(sset_ids);
365   safe_free(elset_ids);
366 
367   safe_free(eblk_stat);
368   safe_free(edblk_stat);
369   safe_free(fablk_stat);
370   safe_free(nset_stat);
371   safe_free(eset_stat);
372   safe_free(fset_stat);
373   safe_free(sset_stat);
374   safe_free(elset_stat);
375   return(EX_FATAL);
376 }
377 
define_dimension(int exoid,const char * DIMENSION,int count,const char * label,int * dimid)378 static int define_dimension(int exoid, const char *DIMENSION, int count, const char *label, int *dimid)
379 {
380   char errmsg[MAX_ERR_LENGTH];
381   int status;
382   if ((status = nc_def_dim(exoid, DIMENSION, count, dimid)) != NC_NOERR) {
383     exerrval = status;
384     if (status == NC_ENAMEINUSE) {
385       sprintf(errmsg,
386               "Error: %s variable name parameters are already defined in file id %d",
387               label, exoid);
388       ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
389     } else {
390       sprintf(errmsg,
391               "Error: failed to define number of %s variables in file id %d",
392               label, exoid);
393       ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
394     }
395   }
396   return status;
397 }
398 
define_variable_name_variable(int exoid,const char * VARIABLE,int dimension,const char * label)399 static int define_variable_name_variable(int exoid, const char *VARIABLE, int dimension, const char *label)
400 {
401   char errmsg[MAX_ERR_LENGTH];
402   int dims[2];
403   int variable;
404   int status;
405 
406   dims[0] = dimension;
407   nc_inq_dimid(exoid, DIM_STR_NAME, &dims[1]); /* Checked earlier, so known to exist */
408 
409   if ((status=nc_def_var(exoid, VARIABLE, NC_CHAR, 2, dims, &variable)) != NC_NOERR) {
410     if (status == NC_ENAMEINUSE) {
411       exerrval = status;
412       sprintf(errmsg,
413               "Error: %s variable names are already defined in file id %d",
414               label, exoid);
415       ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
416 
417     } else {
418       exerrval = status;
419       sprintf(errmsg,
420               "Error: failed to define %s variable names in file id %d",
421               label, exoid);
422       ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
423     }
424   }
425   return status;
426 }
427 
get_status_array(int exoid,int var_count,const char * VARIABLE,const char * label)428 static int *get_status_array(int exoid, int var_count, const char *VARIABLE, const char *label)
429 {
430   char errmsg[MAX_ERR_LENGTH];
431   int varid;
432   int status;
433   int *stat_vals = NULL;
434 
435   if (!(stat_vals = malloc(var_count*sizeof(int)))) {
436     exerrval = EX_MEMFAIL;
437     sprintf(errmsg,
438             "Error: failed to allocate memory for %s status array for file id %d",
439             label, exoid);
440     ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
441     return (NULL);
442   }
443 
444   /* get variable id of status array */
445   if ((nc_inq_varid (exoid, VARIABLE, &varid)) == NC_NOERR) {
446     /* if status array exists (V 2.01+), use it, otherwise assume
447        object exists to be backward compatible */
448 
449     if ((status = nc_get_var_int(exoid, varid, stat_vals)) != NC_NOERR) {
450       exerrval = status;
451       safe_free(stat_vals);
452       sprintf(errmsg,
453               "Error: failed to get %s status array from file id %d",
454               label, exoid);
455       ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
456       return (NULL);
457     }
458   } else {
459     /* status array doesn't exist (V2.00), dummy one up for later checking */
460     int i;
461     for(i=0; i<var_count; i++)
462       stat_vals[i] = 1;
463   }
464  return stat_vals;
465 }
466 
safe_free(void * array)467 static void *safe_free(void *array)
468 {
469   if (array != 0) free(array);
470   return 0;
471 }
472 
put_truth_table(int exoid,int varid,int * table,const char * label)473 static int put_truth_table(int exoid, int varid, int *table, const char *label)
474 {
475   int  iresult = 0;
476   char errmsg[MAX_ERR_LENGTH];
477 
478   iresult = nc_put_var_int(exoid, varid, table);
479 
480   if (iresult != NC_NOERR) {
481     exerrval = iresult;
482     sprintf(errmsg,
483             "Error: failed to store %s variable truth table in file id %d",
484             label, exoid);
485     ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
486    }
487   return iresult;
488 }
489 
define_truth_table(ex_entity_type obj_type,int exoid,int num_ent,int num_var,int * var_tab,int * status_tab,void_int * ids,const char * label)490 static int define_truth_table(ex_entity_type obj_type, int exoid, int num_ent, int num_var,
491 			      int *var_tab, int *status_tab, void_int *ids, const char *label)
492 {
493   char errmsg[MAX_ERR_LENGTH];
494   int k = 0;
495   int i, j;
496   int time_dim;
497   int dims[2];
498   int varid;
499   int status;
500 
501   nc_inq_dimid(exoid, DIM_TIME, &time_dim);
502 
503   if (var_tab == NULL) {
504     exerrval = EX_NULLENTITY;
505     sprintf(errmsg,
506             "Error: %s variable truth table is NULL in file id %d", label, exoid);
507     ex_err("ex_put_all_var_param_ext",errmsg, exerrval);
508     return -1;
509   }
510 
511   for (i=0; i<num_ent; i++) {
512     int64_t id;
513     if (ex_int64_status(exoid) & EX_IDS_INT64_API)
514       id = ((int64_t*)ids)[i];
515     else
516       id = ((int*)ids)[i];
517 
518     for (j=1; j<=num_var; j++) {
519 
520       /* check if variables are to be put out for this block */
521       if (var_tab[k] != 0) {
522         if (status_tab[i] != 0) {/* only define variable if active */
523           dims[0] = time_dim;
524 
525           /* Determine number of entities in entity */
526           /* Need way to make this more generic... */
527           status = nc_inq_dimid(exoid, ex_dim_num_entries_in_object( obj_type, i+1 ), &dims[1]);
528           if (status != NC_NOERR) {
529             exerrval = status;
530             sprintf(errmsg,
531                     "Error: failed to locate number of entities in %s %"PRId64" in file id %d",
532                     label, id, exoid);
533             ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
534             return status;
535           }
536 
537           /* define netCDF variable to store variable values;
538            * the j index cycles from 1 through the number of variables so
539            * that the index of the EXODUS II variable (which is part of
540            * the name of the netCDF variable) will begin at 1 instead of 0
541            */
542           status = nc_def_var(exoid, ex_name_var_of_object( obj_type, j, i+1 ),
543 			      nc_flt_code(exoid), 2, dims, &varid);
544           if (status != NC_NOERR) {
545             if (status != NC_ENAMEINUSE) {
546               exerrval = status;
547               sprintf(errmsg,
548                       "Error: failed to define %s variable for %s %"PRId64" in file id %d",
549                       label, label, id, exoid);
550               ex_err("ex_put_all_var_param_ext",errmsg,exerrval);
551               return status;
552             }
553           }
554 	  ex_compress_variable(exoid, varid, 2);
555         }
556       }  /* if */
557       k++; /* increment truth table pointer */
558     }  /* for j */
559   }  /* for i */
560   return NC_NOERR;
561 }
562