1 /*
2 * Copyright (c) 2005 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 * expvtt - ex_put_truth_table
38 *
39 * entry conditions -
40 * input parameters:
41 * int exoid exodus file id
42 * int obj_type object type
43 * int num_blk number of blocks
44 * int num_var number of variables
45 * int* variable_table variable truth table array
46 *
47 * exit conditions -
48 *
49 * revision history -
50 *
51 *
52 *****************************************************************************/
53
54 #include <stdlib.h>
55 #include "exodusII.h"
56 #include "exodusII_int.h"
57
58 /*!
59 * writes the EXODUS II variable truth table to the database; also,
60 * creates netCDF variables in which to store EXODUS II variable
61 * values; although this table isn't required (because the netCDF
62 * variables can also be created in ex_put_var), this call will save
63 * tremendous time because all of the variables are defined at once
64 * while the file is in define mode, rather than going in and out of
65 * define mode (causing the entire file to be copied over and over)
66 * which is what occurs when the variables are defined in ex_put_var
67 * \param exoid exodus file id
68 * \param obj_type object type
69 * \param num_blk number of blocks
70 * \param num_var number of variables
71 * \param *var_tab variable truth table array
72 */
73
ex_put_truth_table(int exoid,ex_entity_type obj_type,int num_blk,int num_var,int * var_tab)74 int ex_put_truth_table (int exoid,
75 ex_entity_type obj_type,
76 int num_blk,
77 int num_var,
78 int *var_tab)
79 {
80 int numelblkdim, numelvardim, timedim, dims[2], varid;
81 char *sta_type, *tab_type;
82 size_t num_entity = 0;
83 size_t num_var_db = 0;
84 int *stat_vals;
85 int i, j, k;
86 int status;
87 char errmsg[MAX_ERR_LENGTH];
88 const char* routine = "ex_put_truth_table";
89
90 /*
91 * The ent_type and the var_name are used to build the netcdf
92 * variables name. Normally this is done via a macro defined in
93 * exodusII_int.h
94 */
95 const char* ent_type = NULL;
96 const char* var_name = NULL;
97 const char* ent_size = NULL;
98 exerrval = 0; /* clear error code */
99
100 ex_get_dimension(exoid, ex_dim_num_objects(obj_type),
101 ex_name_of_object(obj_type), &num_entity, &numelblkdim, routine);
102
103 if (obj_type == EX_ELEM_BLOCK) {
104 ex_get_dimension(exoid, DIM_NUM_ELE_VAR, "element variables",
105 &num_var_db, &numelvardim, routine);
106 nc_inq_varid (exoid, VAR_ELEM_TAB, &varid);
107 var_name = "vals_elem_var";
108 ent_type = "eb";
109 ent_size = "num_el_in_blk";
110 sta_type = VAR_STAT_EL_BLK;
111 tab_type = VAR_ELEM_TAB;
112 }
113 else if (obj_type == EX_EDGE_BLOCK) {
114 ex_get_dimension(exoid, DIM_NUM_EDG_VAR, "edge block variables",
115 &num_var_db, &numelvardim, routine);
116 nc_inq_varid (exoid, VAR_EBLK_TAB, &varid);
117 var_name = "vals_edge_var";
118 ent_type = "eb";
119 ent_size = "num_ed_in_blk";
120 sta_type = VAR_STAT_ED_BLK;
121 tab_type = VAR_EBLK_TAB;
122 }
123 else if (obj_type == EX_FACE_BLOCK) {
124 ex_get_dimension(exoid, DIM_NUM_FAC_VAR, "face block variables",
125 &num_var_db, &numelvardim, routine);
126 nc_inq_varid (exoid, VAR_FBLK_TAB, &varid);
127 var_name = "vals_face_var";
128 ent_type = "fb";
129 ent_size = "num_fa_in_blk";
130 sta_type = VAR_STAT_FA_BLK;
131 tab_type = VAR_FBLK_TAB;
132 }
133 else if (obj_type == EX_SIDE_SET) {
134 ex_get_dimension(exoid, DIM_NUM_SSET_VAR, "sideset variables",
135 &num_var_db, &numelvardim, routine);
136 nc_inq_varid (exoid, VAR_SSET_TAB, &varid);
137 var_name = "vals_sset_var";
138 ent_type = "ss";
139 ent_size = "num_side_ss";
140 sta_type = VAR_SS_STAT;
141 tab_type = VAR_SSET_TAB;
142 }
143 else if (obj_type == EX_NODE_SET) {
144 ex_get_dimension(exoid, DIM_NUM_NSET_VAR, "nodeset variables",
145 &num_var_db, &numelvardim, routine);
146 nc_inq_varid (exoid, VAR_NSET_TAB, &varid);
147 var_name = "vals_nset_var";
148 ent_type = "ns";
149 ent_size = "num_nod_ns";
150 sta_type = VAR_NS_STAT;
151 tab_type = VAR_NSET_TAB;
152 }
153 else if (obj_type == EX_EDGE_SET) {
154 ex_get_dimension(exoid, DIM_NUM_ESET_VAR, "edge set variables",
155 &num_var_db, &numelvardim, routine);
156 nc_inq_varid (exoid, VAR_ESET_TAB, &varid);
157 var_name = "vals_eset_var";
158 ent_type = "es";
159 ent_size = "num_edge_es";
160 sta_type = VAR_ES_STAT;
161 tab_type = VAR_ESET_TAB;
162 }
163 else if (obj_type == EX_FACE_SET) {
164 ex_get_dimension(exoid, DIM_NUM_FSET_VAR, "face set variables",
165 &num_var_db, &numelvardim, routine);
166 nc_inq_varid (exoid, VAR_FSET_TAB, &varid);
167 var_name = "vals_fset_var";
168 ent_type = "fs";
169 ent_size = "num_face_fs";
170 sta_type = VAR_FS_STAT;
171 tab_type = VAR_FSET_TAB;
172 }
173 else if (obj_type == EX_ELEM_SET) {
174 ex_get_dimension(exoid, DIM_NUM_ELSET_VAR, "element set variables",
175 &num_var_db, &numelvardim, routine);
176 nc_inq_varid (exoid, VAR_ELSET_TAB, &varid);
177 var_name = "vals_elset_var";
178 ent_type = "es";
179 ent_size = "num_ele_els";
180 sta_type = VAR_ELS_STAT;
181 tab_type = VAR_ELSET_TAB;
182 }
183
184 else { /* invalid variable type */
185 exerrval = EX_BADPARAM;
186 sprintf(errmsg,
187 "Error: Invalid variable type %d specified in file id %d",
188 obj_type, exoid);
189 ex_err("ex_get_varid",errmsg,exerrval);
190 return (EX_WARN);
191 }
192
193 if ((int)num_entity != num_blk) {
194 exerrval = EX_FATAL;
195 sprintf(errmsg,
196 "Error: # of %s doesn't match those defined in file id %d",
197 ex_name_of_object(obj_type), exoid);
198 ex_err("ex_get_var_tab",errmsg,exerrval);
199 return (EX_FATAL);
200 }
201
202 if ((int)num_var_db != num_var) {
203 exerrval = EX_FATAL;
204 sprintf(errmsg,
205 "Error: # of %s variables doesn't match those defined in file id %d",
206 ex_name_of_object(obj_type), exoid);
207 ex_err("ex_get_var_tab",errmsg,exerrval);
208 return (EX_FATAL);
209 }
210
211 /* Get status array for later use */
212 if (!(stat_vals = malloc(num_blk*sizeof(int)))) {
213 exerrval = EX_MEMFAIL;
214 sprintf(errmsg,
215 "Error: failed to allocate memory for %s status array for file id %d",
216 ex_name_of_object(obj_type), exoid);
217 ex_err(routine,errmsg,exerrval);
218 return (EX_FATAL);
219 }
220
221 status = nc_inq_varid (exoid, sta_type, &varid);
222
223 /* get variable id of status array */
224 if (status == NC_NOERR) {
225 /* if status array exists (V 2.01+), use it, otherwise assume
226 object exists to be backward compatible */
227
228 if ((status = nc_get_var_int (exoid, varid, stat_vals)) != NC_NOERR) {
229 exerrval = status;
230 free(stat_vals);
231 sprintf(errmsg,
232 "Error: failed to get %s status array from file id %d",
233 ex_name_of_object(obj_type), exoid);
234 ex_err("put_var_tab",errmsg,exerrval);
235 return (EX_FATAL);
236 }
237 } else {
238 /* status array doesn't exist (V2.00), dummy one up for later checking */
239 for(i=0;i<num_blk;i++)
240 stat_vals[i] = 1;
241 }
242
243 /* put netcdf file into define mode */
244 if ((status = nc_redef (exoid)) != NC_NOERR) {
245 free(stat_vals);
246 exerrval = status;
247 sprintf(errmsg,
248 "Error: failed to put file id %d into define mode",
249 exoid);
250 ex_err(routine,errmsg,exerrval);
251 return (EX_FATAL);
252 }
253
254 /* inquire previously defined dimensions */
255 if ((status = nc_inq_dimid (exoid, DIM_TIME, &timedim)) != NC_NOERR) {
256 exerrval = status;
257 free(stat_vals);
258 sprintf(errmsg,
259 "Error: failed to locate time variable in file id %d",
260 exoid);
261 ex_err(routine,errmsg,exerrval);
262 goto error_ret; /* exit define mode and return */
263 }
264
265 /* define netCDF variables in which to store EXODUS II element
266 * variable values
267 */
268
269 k = 0;
270 for (i=0; i<num_blk; i++) {
271 for (j=1; j<=num_var; j++) {
272
273 /* check if variables are to be put out for this entity */
274 if (var_tab[k] != 0) {
275 if (stat_vals[i] != 0) {/* check for NULL entity */
276 /* NOTE: This code used to zero out the var_tab entry
277 if the stat_vals[i] value was zero. However, in some
278 cases it is good to know that a variable was assigned to
279 an entity even if that entity is empty. The code was
280 changed to not modify the truth table.
281 */
282 dims[0] = timedim;
283
284 /* Determine number of entities in block */
285 if ((status = nc_inq_dimid(exoid, ex_catstr(ent_size, (i+1)), &dims[1])) != NC_NOERR) {
286 exerrval = status;
287 free(stat_vals);
288 sprintf(errmsg,
289 "Error: failed to locate number of entities in %d'th %s in file id %d",
290 i+1, ex_name_of_object(obj_type), exoid);
291 ex_err(routine,errmsg,exerrval);
292 goto error_ret; /* exit define mode and return */
293 }
294
295
296 /* define netCDF variable to store variable values; the j
297 * index cycles from 1 through the number of variables so
298 * that the index of the EXODUS II variable (which is part
299 * of the name of the netCDF variable) will begin at 1
300 * instead of 0
301 */
302
303 if ((status = nc_def_var(exoid, ex_catstr2(var_name, j, ent_type, i+1),
304 nc_flt_code(exoid), 2, dims, &varid)) != NC_NOERR) {
305 if (status != NC_ENAMEINUSE) {
306 exerrval = status;
307 free(stat_vals);
308 sprintf(errmsg,
309 "Error: failed to define variable for %d'th %s in file id %d",
310 i+1, ex_name_of_object(obj_type), exoid);
311 ex_err(routine,errmsg,exerrval);
312 goto error_ret; /* exit define mode and return */
313 }
314 ex_compress_variable(exoid, varid, 2);
315 }
316 }
317 } /* if */
318 k++; /* increment element truth table pointer */
319 } /* for j */
320 } /* for i */
321
322 free (stat_vals);
323
324 /* create a variable array in which to store the truth table
325 */
326
327 dims[0] = numelblkdim;
328 dims[1] = numelvardim;
329 status = nc_def_var (exoid, tab_type, NC_INT, 2, dims, &varid);
330
331 if (status != NC_NOERR) {
332 exerrval = status;
333 sprintf(errmsg,
334 "Error: failed to define %s variable truth table in file id %d",
335 ex_name_of_object(obj_type), exoid);
336 ex_err(routine,errmsg,exerrval);
337 goto error_ret; /* exit define mode and return */
338 }
339
340 /* leave define mode */
341 if ((status = nc_enddef (exoid)) != NC_NOERR) {
342 exerrval = status;
343 sprintf(errmsg,
344 "Error: failed to complete definitions in file id %d",
345 exoid);
346 ex_err(routine,errmsg,exerrval);
347 return (EX_FATAL);
348 }
349
350 /* write out the element variable truth table */
351 status = nc_put_var_int(exoid, varid, var_tab);
352
353 if (status != NC_NOERR) {
354 exerrval = status;
355 sprintf(errmsg,
356 "Error: failed to store variable truth table in file id %d",
357 exoid);
358 ex_err(routine,errmsg,exerrval);
359 return (EX_FATAL);
360 }
361
362
363 return (EX_NOERR);
364
365 /* Fatal error: exit definition mode and return */
366 error_ret:
367 if (nc_enddef (exoid) != NC_NOERR) /* exit define mode */
368 {
369 sprintf(errmsg,
370 "Error: failed to complete definition for file id %d",
371 exoid);
372 ex_err(routine,errmsg,exerrval);
373 }
374 return (EX_FATAL);
375 }
376