1 /*
2 * Copyright (c) 2005-2017 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 * 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 NTESS 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 /*****************************************************************************/
38 /*****************************************************************************/
39 /* Function(s) contained in this file:
40 *
41 * ex_leavedef()
42 * ne_id_lkup()
43 * ex_get_file_type()
44 * ex_put_nemesis_version()
45 * ne_check_file_version()
46 * ex_get_idx()
47 *
48 *****************************************************************************
49 * Much of this code is a modified version of what is found in NemesisI.
50 */
51 /*****************************************************************************/
52 /*****************************************************************************/
53 /*****************************************************************************/
54
55 #include <exodusII.h> // for ex_err, etc
56 #include <exodusII_int.h> // for EX_FATAL, EX_NOERR, etc
57 #include <vtk_netcdf.h> // for NC_NOERR, nc_inq_varid, etc
58 #include <stddef.h> // for size_t
59 #include <stdio.h>
60 #include <stdlib.h> // for malloc
61 #include <string.h> // for strcpy, strlen
62 #include <sys/types.h> // for int64_t
63
64 /* Global variables */
65 char *ne_ret_string;
66
ex_leavedef(int exoid,const char * call_rout)67 int ex_leavedef(int exoid, const char *call_rout)
68 {
69 char errmsg[MAX_ERR_LENGTH];
70 int status;
71
72 if ((status = nc_enddef(exoid)) != NC_NOERR) {
73 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to end define mode for file id %d", exoid);
74 ex_err(call_rout, errmsg, status);
75
76 return (EX_FATAL);
77 }
78 return (EX_NOERR);
79 }
80
81 /*****************************************************************************/
82 /*****************************************************************************/
83 /*****************************************************************************/
84 /* Note: This function assumes a 1-d vector of data for "ne_var_name".
85 */
86 /*****************************************************************************/
ne_id_lkup(int exoid,const char * ne_var_name,int64_t * idx,ex_entity_id ne_var_id)87 int ne_id_lkup(int exoid, const char *ne_var_name, int64_t *idx, ex_entity_id ne_var_id)
88 {
89 int status;
90 int varid, ndims, dimid[1], ret = -1;
91 nc_type var_type;
92 size_t length, start[1];
93 int64_t my_index, begin, end;
94 long long id_val;
95
96 char errmsg[MAX_ERR_LENGTH];
97
98 if ((status = nc_inq_varid(exoid, ne_var_name, &varid)) != NC_NOERR) {
99 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find variable ID for \"%s\" in file ID %d",
100 ne_var_name, exoid);
101 ex_err(__func__, errmsg, status);
102 return (EX_FATAL);
103 }
104
105 /* check if I need the length for this variable */
106 if (idx[1] == -1) {
107 /* Get the dimension IDs for this variable */
108 if ((status = nc_inq_var(exoid, varid, (char *)0, &var_type, &ndims, dimid, (int *)0)) !=
109 NC_NOERR) {
110 snprintf(errmsg, MAX_ERR_LENGTH,
111 "ERROR: failed to find dimension ID for variable \"%s\" "
112 "in file ID %d",
113 ne_var_name, exoid);
114 ex_err(__func__, errmsg, status);
115 return (-1);
116 }
117
118 /* Get the length of this variable */
119 if ((status = nc_inq_dimlen(exoid, dimid[0], &length)) != NC_NOERR) {
120 snprintf(errmsg, MAX_ERR_LENGTH,
121 "ERROR: failed to find dimension for variable \"%s\" in file ID %d", ne_var_name,
122 exoid);
123 ex_err(__func__, errmsg, status);
124 return (-1);
125 }
126
127 idx[1] = length;
128 } /* End "if (idx[1] == -1)" */
129
130 begin = idx[0];
131 end = idx[1];
132
133 /* Find the index by looping over each entry */
134 for (my_index = begin; my_index < end; my_index++) {
135 start[0] = my_index;
136 status = nc_get_var1_longlong(exoid, varid, start, &id_val);
137
138 if (status != NC_NOERR) {
139 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find variable \"%s\" in file ID %d",
140 ne_var_name, exoid);
141 ex_err(__func__, errmsg, status);
142 return (-1);
143 }
144
145 if (id_val == ne_var_id) {
146 ret = (int)my_index;
147 break;
148 }
149 }
150 return (ret);
151 }
152
153 /*****************************************************************************/
154 /*****************************************************************************/
155 /*****************************************************************************/
156 /* This function retrieves the file type from a Nemesis file.
157 */
158 /*****************************************************************************/
ex_get_file_type(int exoid,char * ftype)159 int ex_get_file_type(int exoid, char *ftype)
160 {
161 int status;
162 int varid;
163 int lftype;
164
165 char errmsg[MAX_ERR_LENGTH];
166
167 EX_FUNC_ENTER();
168
169 if ((status = nc_inq_varid(exoid, VAR_FILE_TYPE, &varid)) != NC_NOERR) {
170
171 /* If no file type is found, assume parallel */
172 ftype[0] = 'p';
173 ftype[1] = '\0';
174
175 EX_FUNC_LEAVE(EX_NOERR);
176 }
177
178 if ((status = nc_get_var1_int(exoid, varid, NULL, &lftype)) != NC_NOERR) {
179 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get variable \"%s\" from file ID %d",
180 VAR_FILE_TYPE, exoid);
181 ex_err(__func__, errmsg, status);
182 EX_FUNC_LEAVE(EX_FATAL);
183 }
184
185 /* Set the appropriate character */
186 if (lftype == 0) {
187 strcpy(ftype, "p");
188 }
189 else if (lftype == 1) {
190 strcpy(ftype, "s");
191 }
192
193 EX_FUNC_LEAVE(EX_NOERR);
194 }
195
196 /*****************************************************************************/
197 /*****************************************************************************/
198 /*****************************************************************************/
199 /* This function outputs the Nemesis version information to the file.
200 */
201 /*****************************************************************************/
ex_put_nemesis_version(int exoid)202 int ex_put_nemesis_version(int exoid)
203 {
204 int status;
205 float file_ver, api_ver;
206
207 char errmsg[MAX_ERR_LENGTH];
208
209 EX_FUNC_ENTER();
210
211 file_ver = NEMESIS_FILE_VERSION;
212 api_ver = NEMESIS_API_VERSION;
213
214 /* Check to see if the nemesis file version is already in the file */
215 if (nc_get_att_float(exoid, NC_GLOBAL, "nemesis_file_version", &file_ver) != NC_NOERR) {
216
217 /* Output the Nemesis file version */
218 if ((status = nc_put_att_float(exoid, NC_GLOBAL, "nemesis_file_version", NC_FLOAT, 1,
219 &file_ver)) != NC_NOERR) {
220 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to output nemesis file version in file ID %d",
221 exoid);
222 ex_err(__func__, errmsg, status);
223 EX_FUNC_LEAVE(EX_FATAL);
224 }
225
226 /* Output the Nemesis API version */
227 if ((status = nc_put_att_float(exoid, NC_GLOBAL, "nemesis_api_version", NC_FLOAT, 1,
228 &api_ver)) != NC_NOERR) {
229 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to output nemesis api version in file ID %d",
230 exoid);
231 ex_err(__func__, errmsg, status);
232 EX_FUNC_LEAVE(EX_FATAL);
233 }
234 }
235 EX_FUNC_LEAVE(EX_NOERR);
236 }
237
238 /*****************************************************************************/
239 /*****************************************************************************/
240 /*****************************************************************************/
241 /* This function checks that the version info is correct.
242 */
243 /*****************************************************************************/
ne_check_file_version(int exoid)244 int ne_check_file_version(int exoid)
245 {
246 #if 0
247 float file_ver;
248
249 int status;
250 char errmsg[MAX_ERR_LENGTH];
251
252 EX_FUNC_ENTER();
253
254 /* Get the file version */
255 if ((status = nc_get_att_float(exoid, NC_GLOBAL, "nemesis_file_version", &file_ver)) != NC_NOERR) {
256 snprintf(errmsg, MAX_ERR_LENGTH,
257 "ERROR: failed to get the nemesis file version from file ID %d",
258 exoid);
259 ex_err(__func__, errmsg, status);
260 EX_FUNC_LEAVE(EX_FATAL);
261 }
262
263 if (fabs(NEMESIS_FILE_VERSION-file_ver) > 0.001) {
264 snprintf(errmsg, MAX_ERR_LENGTH,
265 "ERROR: Nemesis version mismatch in file ID %d!\n", exoid);
266 ex_err(__func__, errmsg, EX_MSG);
267 EX_FUNC_LEAVE(EX_FATAL);
268 }
269 EX_FUNC_LEAVE(EX_NOERR);
270 #else
271 return EX_NOERR;
272 #endif
273 }
274
275 /*****************************************************************************/
276 /*****************************************************************************/
277 /*****************************************************************************/
278 /* This function gets the index for the given variable at the
279 * position given.
280 */
281 /*****************************************************************************/
ex_get_idx(int exoid,const char * ne_var_name,int64_t * my_index,int pos)282 int ex_get_idx(int exoid, const char *ne_var_name, int64_t *my_index, int pos)
283 {
284 int status;
285 int varid;
286 size_t start[1], count[1];
287 #if NC_HAS_HDF5
288 long long varidx[2];
289 #else
290 int varidx[2];
291 #endif
292 char errmsg[MAX_ERR_LENGTH];
293 /*-----------------------------Execution begins-----------------------------*/
294 EX_FUNC_ENTER();
295
296 /* set default values for idx */
297 my_index[0] = 0;
298 my_index[1] = -1;
299
300 /*
301 * assume that if there is an error returned, that this
302 * means that this is a parallel file, and the index does
303 * not exists. This is not an error
304 */
305 if ((status = nc_inq_varid(exoid, ne_var_name, &varid)) == NC_NOERR) {
306 /* check if we are at the beginning of the index vector */
307 if (pos == 0) {
308 start[0] = pos;
309 count[0] = 1;
310 }
311 else {
312 start[0] = pos - 1;
313 count[0] = 2;
314 }
315
316 #if NC_HAS_HDF5
317 status = nc_get_vara_longlong(exoid, varid, start, count, varidx);
318 #else
319 status = nc_get_vara_int(exoid, varid, start, count, varidx);
320 #endif
321 if (status != NC_NOERR) {
322 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find variable \"%s\" in file ID %d",
323 ne_var_name, exoid);
324 ex_err(__func__, errmsg, status);
325 EX_FUNC_LEAVE(-1);
326 }
327
328 if (pos == 0) {
329 my_index[0] = 0;
330 my_index[1] = varidx[0];
331 }
332 else {
333 my_index[0] = varidx[0];
334 my_index[1] = varidx[1];
335 }
336 }
337 EX_FUNC_LEAVE(1);
338 }
339