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 #include "exodusII.h" // for ex_err, etc
37 #include "exodusII_int.h" // for EX_FATAL, EX_WARN, etc
38 #include "vtk_netcdf.h" // for NC_NOERR, nc_get_att_text, etc
39 #include <inttypes.h> // for PRId64
40 #include <stddef.h> // for size_t
41 #include <stdio.h>
42 #include <string.h> // for memset, strcmp
43 #include <sys/types.h> // for int64_t
44
45 /*!
46
47 The function ex_get_prop() reads an integer object property value
48 stored for a single element block, node set, or side set.
49
50 \return In case of an error, ex_get_prop() returns a negative number; a
51 warning will return a positive number. Possible causes of errors
52 include:
53 - data file not properly opened with call to ex_create() or ex_open()
54 - invalid object type specified.
55 - a warning value is returned if a property with the specified name is not
56 found.
57
58 \param[in] exoid exodus file ID returned from a previous call to
59 ex_create() or ex_open().
60 \param[in] obj_type Type of object; use one of the options in the table below.
61 \param[in] obj_id The element block, node set, or side set ID.
62 \param[in] prop_name The name of the property (maximum length is \p
63 MAX_STR_LENGTH ) for
64 which the value is desired.
65 \param[out] value Returned value of the property.
66
67 | ex_entity_type | description |
68 | -------------- | ------------------------- |
69 | EX_NODE_SET | Node Set entity type |
70 | EX_EDGE_BLOCK | Edge Block entity type |
71 | EX_EDGE_SET | Edge Set entity type |
72 | EX_FACE_BLOCK | Face Block entity type |
73 | EX_FACE_SET | Face Set entity type |
74 | EX_ELEM_BLOCK | Element Block entity type|
75 | EX_ELEM_SET | Element Set entity type |
76 | EX_SIDE_SET | Side Set entity type |
77 | EX_ELEM_MAP | Element Map entity type |
78 | EX_NODE_MAP | Node Map entity type |
79 | EX_EDGE_MAP | Edge Map entity type |
80 | EX_FACE_MAP | Face Map entity type |
81
82
83 For an example of code to read an object property, refer to the
84 description for ex_get_prop_names().
85
86 */
87
ex_get_prop(int exoid,ex_entity_type obj_type,ex_entity_id obj_id,const char * prop_name,void_int * value)88 int ex_get_prop(int exoid, ex_entity_type obj_type, ex_entity_id obj_id, const char *prop_name,
89 void_int *value)
90 {
91 int status;
92 int num_props, i, propid;
93 int found = EX_FALSE;
94 size_t start[1];
95 char * name;
96 char tmpstr[MAX_STR_LENGTH + 1];
97
98 char errmsg[MAX_ERR_LENGTH];
99
100 EX_FUNC_ENTER();
101 ex_check_valid_file_id(exoid, __func__);
102
103 /* open appropriate variable, depending on obj_type and prop_name */
104 num_props = ex_get_num_props(exoid, obj_type);
105
106 for (i = 1; i <= num_props; i++) {
107 switch (obj_type) {
108 case EX_ELEM_BLOCK: name = VAR_EB_PROP(i); break;
109 case EX_EDGE_BLOCK: name = VAR_ED_PROP(i); break;
110 case EX_FACE_BLOCK: name = VAR_FA_PROP(i); break;
111 case EX_NODE_SET: name = VAR_NS_PROP(i); break;
112 case EX_EDGE_SET: name = VAR_ES_PROP(i); break;
113 case EX_FACE_SET: name = VAR_FS_PROP(i); break;
114 case EX_ELEM_SET: name = VAR_ELS_PROP(i); break;
115 case EX_SIDE_SET: name = VAR_SS_PROP(i); break;
116 case EX_ELEM_MAP: name = VAR_EM_PROP(i); break;
117 case EX_FACE_MAP: name = VAR_FAM_PROP(i); break;
118 case EX_EDGE_MAP: name = VAR_EDM_PROP(i); break;
119 case EX_NODE_MAP: name = VAR_NM_PROP(i); break;
120 default:
121 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: object type %d not supported; file id %d", obj_type,
122 exoid);
123 ex_err(__func__, errmsg, EX_BADPARAM);
124 EX_FUNC_LEAVE(EX_FATAL);
125 }
126
127 if ((status = nc_inq_varid(exoid, name, &propid)) != NC_NOERR) {
128 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to locate property array %s in file id %d",
129 name, exoid);
130 ex_err(__func__, errmsg, status);
131 EX_FUNC_LEAVE(EX_FATAL);
132 }
133
134 /* compare stored attribute name with passed property name */
135 memset(tmpstr, 0, MAX_STR_LENGTH + 1);
136 if ((status = nc_get_att_text(exoid, propid, ATT_PROP_NAME, tmpstr)) != NC_NOERR) {
137 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get property name in file id %d", exoid);
138 ex_err(__func__, errmsg, status);
139 EX_FUNC_LEAVE(EX_FATAL);
140 }
141
142 if (strcmp(tmpstr, prop_name) == 0) {
143 found = EX_TRUE;
144 break;
145 }
146 }
147
148 /* if property is not found, return warning */
149 if (!found) {
150 snprintf(errmsg, MAX_ERR_LENGTH, "Warning: %s property %s not defined in file id %d",
151 ex_name_of_object(obj_type), prop_name, exoid);
152 ex_err(__func__, errmsg, EX_BADPARAM);
153 EX_FUNC_LEAVE(EX_WARN);
154 }
155
156 /* find index into property array using obj_id; read value from property */
157 /* array at proper index; ex_id_lkup returns an index that is 1-based, */
158 /* but netcdf expects 0-based arrays so subtract 1 */
159 status = ex_id_lkup(exoid, obj_type, obj_id);
160 if (status > 0) {
161 start[0] = status - 1;
162 }
163 else {
164 ex_get_err(NULL, NULL, &status);
165
166 if (status != 0) {
167 if (status == EX_NULLENTITY) {
168 snprintf(errmsg, MAX_ERR_LENGTH, "Warning: %s id %" PRId64 " is NULL in file id %d",
169 ex_name_of_object(obj_type), obj_id, exoid);
170 ex_err(__func__, errmsg, EX_NULLENTITY);
171 EX_FUNC_LEAVE(EX_WARN);
172 }
173 snprintf(errmsg, MAX_ERR_LENGTH,
174 "ERROR: failed to locate id %" PRId64 " in %s property array in file id %d", obj_id,
175 ex_name_of_object(obj_type), exoid);
176 ex_err(__func__, errmsg, status);
177 EX_FUNC_LEAVE(EX_FATAL);
178 }
179 }
180
181 if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
182 long long l_val;
183 status = nc_get_var1_longlong(exoid, propid, start, &l_val);
184 if (status == NC_NOERR) {
185 int64_t *val = (int64_t *)value;
186 *val = l_val;
187 }
188 }
189 else {
190 int i_val;
191 status = nc_get_var1_int(exoid, propid, start, &i_val);
192 if (status == NC_NOERR) {
193 int *val = (int *)value;
194 *val = i_val;
195 }
196 }
197
198 if (status != NC_NOERR) {
199 snprintf(errmsg, MAX_ERR_LENGTH,
200 "ERROR: failed to read value in %s property array in file id %d",
201 ex_name_of_object(obj_type), exoid);
202 ex_err(__func__, errmsg, status);
203 EX_FUNC_LEAVE(EX_FATAL);
204 }
205
206 EX_FUNC_LEAVE(EX_NOERR);
207 }
208