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