1 /*
2 * Copyright(C) 1999-2020 National Technology & Engineering Solutions
3 * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
4 * NTESS, the U.S. Government retains certain rights in this software.
5 *
6 * See packages/seacas/LICENSE for details
7 */
8
9 #include "exodusII.h" // for ex_err, etc
10 #include "exodusII_int.h" // for EX_FATAL, ex__get_dimension, etc
11
ex__look_up_var(int exoid,ex_entity_type var_type,int var_index,ex_entity_id obj_id,const char * VOBJID,const char * VOBJTAB,const char * DNUMOBJ,const char * DNUMOBJVAR,int * varid)12 static int ex__look_up_var(int exoid, ex_entity_type var_type, int var_index, ex_entity_id obj_id,
13 const char *VOBJID, const char *VOBJTAB, const char *DNUMOBJ,
14 const char *DNUMOBJVAR, int *varid)
15 {
16 int status;
17 int obj_id_ndx;
18 int dimid, time_dim, numobjdim, dims[2];
19
20 size_t num_obj;
21 size_t num_obj_var;
22 size_t num_entity;
23
24 int *obj_var_truth_tab;
25 char errmsg[MAX_ERR_LENGTH];
26
27 if (var_type == EX_ASSEMBLY) {
28 status = nc_inq_varid(exoid, VAR_ENTITY_ASSEMBLY(obj_id), varid);
29 if (status != 0) {
30 snprintf(errmsg, MAX_ERR_LENGTH,
31 "ERROR: failed to locate %s id %" PRId64 " in %s array in file id %d",
32 ex_name_of_object(var_type), obj_id, VOBJID, exoid);
33 ex_err_fn(exoid, __func__, errmsg, status);
34 return (EX_FATAL);
35 }
36 obj_id_ndx = obj_id;
37 }
38 else if (var_type == EX_BLOB) {
39 status = nc_inq_varid(exoid, VAR_ENTITY_BLOB(obj_id), varid);
40 if (status != 0) {
41 snprintf(errmsg, MAX_ERR_LENGTH,
42 "ERROR: failed to locate %s id %" PRId64 " in %s array in file id %d",
43 ex_name_of_object(var_type), obj_id, VOBJID, exoid);
44 ex_err_fn(exoid, __func__, errmsg, status);
45 return (EX_FATAL);
46 }
47 obj_id_ndx = obj_id;
48 }
49 else {
50 /* Determine index of obj_id in VOBJID array */
51 obj_id_ndx = ex__id_lkup(exoid, var_type, obj_id);
52 if (obj_id_ndx <= 0) {
53 ex_get_err(NULL, NULL, &status);
54
55 if (status != 0) {
56 if (status == EX_NULLENTITY) {
57 snprintf(errmsg, MAX_ERR_LENGTH,
58 "Warning: no variables allowed for NULL block %" PRId64 " in file id %d", obj_id,
59 exoid);
60 ex_err_fn(exoid, __func__, errmsg, EX_NULLENTITY);
61 return (EX_WARN);
62 }
63
64 snprintf(errmsg, MAX_ERR_LENGTH,
65 "ERROR: failed to locate %s id %" PRId64 " in %s array in file id %d",
66 ex_name_of_object(var_type), obj_id, VOBJID, exoid);
67 ex_err_fn(exoid, __func__, errmsg, status);
68 return (EX_FATAL);
69 }
70 }
71 }
72
73 if ((status = nc_inq_varid(exoid, ex__name_var_of_object(var_type, var_index, obj_id_ndx),
74 varid)) != NC_NOERR) {
75 if (status == NC_ENOTVAR) { /* variable doesn't exist, create it! */
76 /* check for the existence of an TNAME variable truth table */
77 if (nc_inq_varid(exoid, VOBJTAB, varid) == NC_NOERR) {
78 /* find out number of TNAMEs and TNAME variables */
79 status = ex__get_dimension(exoid, DNUMOBJ, ex_name_of_object(var_type), &num_obj, &dimid,
80 __func__);
81 if (status != NC_NOERR) {
82 return (status);
83 }
84
85 status = ex__get_dimension(exoid, DNUMOBJVAR, ex_name_of_object(var_type), &num_obj_var,
86 &dimid, __func__);
87 if (status != NC_NOERR) {
88 return (status);
89 }
90
91 if (!(obj_var_truth_tab = malloc(num_obj * num_obj_var * sizeof(int)))) {
92 snprintf(errmsg, MAX_ERR_LENGTH,
93 "ERROR: failed to allocate memory for %s variable "
94 "truth table in file id %d",
95 ex_name_of_object(var_type), exoid);
96 ex_err_fn(exoid, __func__, errmsg, EX_MEMFAIL);
97 return (EX_FATAL);
98 }
99
100 /* read in the TNAME variable truth table */
101 if ((status = nc_get_var_int(exoid, *varid, obj_var_truth_tab)) != NC_NOERR) {
102 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get truth table from file id %d",
103 exoid);
104 ex_err_fn(exoid, __func__, errmsg, status);
105 return (EX_FATAL);
106 }
107
108 if (obj_var_truth_tab[num_obj_var * (obj_id_ndx - 1) + var_index - 1] == 0L) {
109 free(obj_var_truth_tab);
110 snprintf(
111 errmsg, MAX_ERR_LENGTH, "ERROR: Invalid %s variable %d, %s %" PRId64 " in file id %d",
112 ex_name_of_object(var_type), var_index, ex_name_of_object(var_type), obj_id, exoid);
113 ex_err_fn(exoid, __func__, errmsg, EX_BADPARAM);
114 return (EX_FATAL);
115 }
116 free(obj_var_truth_tab);
117 }
118
119 if ((status = nc_inq_dimid(exoid, DIM_TIME, &time_dim)) != NC_NOERR) {
120 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to locate time dimension in file id %d",
121 exoid);
122 ex_err_fn(exoid, __func__, errmsg, status);
123 goto error_ret; /* exit define mode and return */
124 }
125
126 ex__get_dimension(exoid, ex__dim_num_entries_in_object(var_type, obj_id_ndx),
127 ex_name_of_object(var_type), &num_entity, &numobjdim, __func__);
128
129 /* variable doesn't exist so put file into define mode */
130 if ((status = nc_redef(exoid)) != NC_NOERR) {
131 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid);
132 ex_err_fn(exoid, __func__, errmsg, status);
133 return (EX_FATAL);
134 }
135
136 /* define netCDF variable to store TNAME variable values */
137 dims[0] = time_dim;
138 dims[1] = numobjdim;
139 if ((status = nc_def_var(exoid, ex__name_var_of_object(var_type, var_index, obj_id_ndx),
140 nc_flt_code(exoid), 2, dims, varid)) != NC_NOERR) {
141 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define %s variable %d in file id %d",
142 ex_name_of_object(var_type), var_index, exoid);
143 ex_err_fn(exoid, __func__, errmsg, status);
144 goto error_ret;
145 }
146 ex__compress_variable(exoid, *varid, 2);
147
148 /* leave define mode */
149 if ((status = ex__leavedef(exoid, __func__)) != NC_NOERR) {
150 return (EX_FATAL);
151 }
152 }
153 else {
154 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to locate %s variable %s in file id %d",
155 ex_name_of_object(var_type), ex__name_var_of_object(var_type, var_index, obj_id_ndx),
156 exoid);
157 ex_err_fn(exoid, __func__, errmsg, status);
158 return (EX_FATAL);
159 }
160 }
161 return (EX_NOERR);
162
163 /* Fatal error: exit definition mode and return */
164 error_ret:
165 ex__leavedef(exoid, __func__);
166 return (EX_FATAL);
167 }
168
169 /*!
170 \ingroup ResultsData
171 * writes the values of a single variable for a partial block at one time
172 * step to the database; assume the first time step and variable index
173 * are 1
174 * \param exoid exodus file id
175 * \param time_step time step number (1-based)
176 * \param var_type type (edge block, face block, edge set, ... )
177 * \param var_index entity variable index (1-based)
178 * \param obj_id entity id
179 * \param start_index index of first entity in block to write (1-based)
180 * \param num_entities number of entries in this block/set
181 * \param var_vals the values to be written
182 */
183
ex_put_partial_var(int exoid,int time_step,ex_entity_type var_type,int var_index,ex_entity_id obj_id,int64_t start_index,int64_t num_entities,const void * var_vals)184 int ex_put_partial_var(int exoid, int time_step, ex_entity_type var_type, int var_index,
185 ex_entity_id obj_id, int64_t start_index, int64_t num_entities,
186 const void *var_vals)
187 {
188 int varid;
189 size_t start[2], count[2];
190 int status;
191 char errmsg[MAX_ERR_LENGTH];
192
193 EX_FUNC_ENTER();
194
195 if (ex__check_valid_file_id(exoid, __func__) == EX_FATAL) {
196 EX_FUNC_LEAVE(EX_FATAL);
197 }
198
199 switch (var_type) {
200 case EX_GLOBAL:
201 if (num_entities <= 0) {
202 snprintf(errmsg, MAX_ERR_LENGTH, "Warning: no global variables specified for file id %d",
203 exoid);
204 ex_err_fn(exoid, __func__, errmsg, EX_BADPARAM);
205
206 EX_FUNC_LEAVE(EX_WARN);
207 }
208 /* inquire previously defined variable */
209
210 if ((status = nc_inq_varid(exoid, VAR_GLO_VAR, &varid)) != NC_NOERR) {
211 if (status == NC_ENOTVAR) {
212 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: no global variables defined in file id %d", exoid);
213 ex_err_fn(exoid, __func__, errmsg, status);
214 }
215 else {
216 snprintf(errmsg, MAX_ERR_LENGTH,
217 "ERROR: failed to get global variables parameters in file id %d", exoid);
218 ex_err_fn(exoid, __func__, errmsg, status);
219 }
220 EX_FUNC_LEAVE(EX_FATAL);
221 }
222 break;
223 case EX_NODAL:
224 status =
225 ex__put_partial_nodal_var(exoid, time_step, var_index, start_index, num_entities, var_vals);
226 EX_FUNC_LEAVE(status);
227 break;
228 case EX_ASSEMBLY:
229 status = ex__look_up_var(exoid, var_type, var_index, obj_id, "", VAR_ASSEMBLY_TAB,
230 DIM_NUM_ASSEMBLY, DIM_NUM_ASSEMBLY_VAR, &varid);
231 break;
232 case EX_BLOB:
233 status = ex__look_up_var(exoid, var_type, var_index, obj_id, "", VAR_BLOB_TAB, DIM_NUM_BLOB,
234 DIM_NUM_BLOB_VAR, &varid);
235 break;
236 case EX_EDGE_BLOCK:
237 status = ex__look_up_var(exoid, var_type, var_index, obj_id, VAR_ID_ED_BLK, VAR_EBLK_TAB,
238 DIM_NUM_ED_BLK, DIM_NUM_EDG_VAR, &varid);
239 break;
240 case EX_FACE_BLOCK:
241 status = ex__look_up_var(exoid, var_type, var_index, obj_id, VAR_ID_FA_BLK, VAR_FBLK_TAB,
242 DIM_NUM_FA_BLK, DIM_NUM_FAC_VAR, &varid);
243 break;
244 case EX_ELEM_BLOCK:
245 status = ex__look_up_var(exoid, var_type, var_index, obj_id, VAR_ID_EL_BLK, VAR_ELEM_TAB,
246 DIM_NUM_EL_BLK, DIM_NUM_ELE_VAR, &varid);
247 break;
248 case EX_NODE_SET:
249 status = ex__look_up_var(exoid, var_type, var_index, obj_id, VAR_NS_IDS, VAR_NSET_TAB,
250 DIM_NUM_NS, DIM_NUM_NSET_VAR, &varid);
251 break;
252 case EX_EDGE_SET:
253 status = ex__look_up_var(exoid, var_type, var_index, obj_id, VAR_ES_IDS, VAR_ESET_TAB,
254 DIM_NUM_ES, DIM_NUM_ESET_VAR, &varid);
255 break;
256 case EX_FACE_SET:
257 status = ex__look_up_var(exoid, var_type, var_index, obj_id, VAR_FS_IDS, VAR_FSET_TAB,
258 DIM_NUM_FS, DIM_NUM_FSET_VAR, &varid);
259 break;
260 case EX_SIDE_SET:
261 status = ex__look_up_var(exoid, var_type, var_index, obj_id, VAR_SS_IDS, VAR_SSET_TAB,
262 DIM_NUM_SS, DIM_NUM_SSET_VAR, &varid);
263 break;
264 case EX_ELEM_SET:
265 status = ex__look_up_var(exoid, var_type, var_index, obj_id, VAR_ELS_IDS, VAR_ELSET_TAB,
266 DIM_NUM_ELS, DIM_NUM_ELSET_VAR, &varid);
267 break;
268 default:
269 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: invalid variable type (%d) specified for file id %d",
270 var_type, exoid);
271 ex_err_fn(exoid, __func__, errmsg, EX_BADPARAM);
272 EX_FUNC_LEAVE(EX_FATAL);
273 }
274
275 if (status != EX_NOERR) {
276 EX_FUNC_LEAVE(status);
277 }
278
279 /* store element variable values */
280 start[0] = time_step - 1;
281 start[1] = start_index - 1;
282 if (var_type == EX_GLOBAL) {
283 /* global variables may be written
284 * - all at once (by setting var_index to 1 and num_entries_this_obj to
285 * num_glob, or
286 * - one at a time (by setting var_index to the desired index and
287 * num_entries_this_obj to 1.
288 */
289 count[0] = var_index;
290 }
291 else {
292 count[0] = 1;
293 }
294 count[1] = num_entities;
295 if (count[1] == 0) {
296 start[1] = 0;
297 }
298
299 if (ex__comp_ws(exoid) == 4) {
300 status = nc_put_vara_float(exoid, varid, start, count, var_vals);
301 }
302 else {
303 status = nc_put_vara_double(exoid, varid, start, count, var_vals);
304 }
305
306 if (status != NC_NOERR) {
307 snprintf(errmsg, MAX_ERR_LENGTH,
308 "ERROR: failed to store %s %" PRId64 " variable %d at step %d in file id %d",
309 ex_name_of_object(var_type), obj_id, var_index, time_step, exoid);
310 ex_err_fn(exoid, __func__, errmsg, status);
311 EX_FUNC_LEAVE(EX_FATAL);
312 }
313
314 EX_FUNC_LEAVE(EX_NOERR);
315 }
316