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  *
10  * exgeat - ex_get_partial_attr
11  *
12  * entry conditions -
13  *   input parameters:
14  *       int     exoid                   exodus file id
15  *       int     obj_type                object type (edge, face, elem block)
16  *       int     obj_id                  object id (edge face, elem block ID)
17  *       int     start_num               starting index of attributes to be
18  *returned.
19  *       int     num_ent                 number of entities to read attributes
20  *for.
21  *
22  * exit conditions -
23  *       float*  attrib                  array of attributes
24  *
25  * revision history -
26  *
27  *
28  *****************************************************************************/
29 
30 #include "exodusII.h"     // for ex_err, etc
31 #include "exodusII_int.h" // for EX_FATAL, ex__get_dimension, etc
32 
33 /*!
34  * reads the specified attribute for a subsect of a block
35  * \param      exoid         exodus file id
36  * \param      obj_type      object type (edge, face, elem block)
37  * \param      obj_id        object id (edge, face, elem block ID)
38  * \param      start_num     the starting index of the attributes to be
39  * returned.
40  * \param      num_ent       the number of entities to read attributes for.
41  * \param      attrib         array of attributes
42  */
43 /*
44  */
ex_get_partial_attr(int exoid,ex_entity_type obj_type,ex_entity_id obj_id,int64_t start_num,int64_t num_ent,void * attrib)45 int ex_get_partial_attr(int exoid, ex_entity_type obj_type, ex_entity_id obj_id, int64_t start_num,
46                         int64_t num_ent, void *attrib)
47 
48 {
49   int         status;
50   int         attrid, obj_id_ndx;
51   int         temp;
52   size_t      num_entries_this_obj, num_attr;
53   size_t      start[2], count[2];
54   char        errmsg[MAX_ERR_LENGTH];
55   const char *dnumobjent;
56   const char *dnumobjatt;
57   const char *vattrbname;
58 
59   EX_FUNC_ENTER();
60   if (ex__check_valid_file_id(exoid, __func__) == EX_FATAL) {
61     EX_FUNC_LEAVE(EX_FATAL);
62   }
63 
64 #if !defined(PARALLEL_AWARE_EXODUS)
65   if (num_ent == 0) {
66     EX_FUNC_LEAVE(EX_NOERR);
67   }
68 #endif
69 
70   /* Determine index of obj_id in vobjids array */
71   if (obj_type != EX_NODAL) {
72     obj_id_ndx = ex__id_lkup(exoid, obj_type, obj_id);
73     if (obj_id_ndx <= 0) {
74       ex_get_err(NULL, NULL, &status);
75 
76       if (status != 0) {
77         if (status == EX_NULLENTITY) {
78           snprintf(errmsg, MAX_ERR_LENGTH,
79                    "Warning: no attributes found for NULL %s %" PRId64 " in file id %d",
80                    ex_name_of_object(obj_type), obj_id, exoid);
81           ex_err_fn(exoid, __func__, errmsg, EX_NULLENTITY);
82           EX_FUNC_LEAVE(EX_WARN); /* no attributes for this object */
83         }
84         snprintf(errmsg, MAX_ERR_LENGTH,
85                  "Warning: failed to locate %s id%" PRId64 " in id array in file id %d",
86                  ex_name_of_object(obj_type), obj_id, exoid);
87         ex_err_fn(exoid, __func__, errmsg, status);
88         EX_FUNC_LEAVE(EX_WARN);
89       }
90     }
91   }
92 
93   switch (obj_type) {
94   case EX_SIDE_SET:
95     dnumobjent = DIM_NUM_SIDE_SS(obj_id_ndx);
96     dnumobjatt = DIM_NUM_ATT_IN_SS(obj_id_ndx);
97     vattrbname = VAR_SSATTRIB(obj_id_ndx);
98     break;
99   case EX_NODE_SET:
100     dnumobjent = DIM_NUM_NOD_NS(obj_id_ndx);
101     dnumobjatt = DIM_NUM_ATT_IN_NS(obj_id_ndx);
102     vattrbname = VAR_NSATTRIB(obj_id_ndx);
103     break;
104   case EX_EDGE_SET:
105     dnumobjent = DIM_NUM_EDGE_ES(obj_id_ndx);
106     dnumobjatt = DIM_NUM_ATT_IN_ES(obj_id_ndx);
107     vattrbname = VAR_ESATTRIB(obj_id_ndx);
108     break;
109   case EX_FACE_SET:
110     dnumobjent = DIM_NUM_FACE_FS(obj_id_ndx);
111     dnumobjatt = DIM_NUM_ATT_IN_FS(obj_id_ndx);
112     vattrbname = VAR_FSATTRIB(obj_id_ndx);
113     break;
114   case EX_ELEM_SET:
115     dnumobjent = DIM_NUM_ELE_ELS(obj_id_ndx);
116     dnumobjatt = DIM_NUM_ATT_IN_ELS(obj_id_ndx);
117     vattrbname = VAR_ELSATTRIB(obj_id_ndx);
118     break;
119   case EX_NODAL:
120     dnumobjent = DIM_NUM_NODES;
121     dnumobjatt = DIM_NUM_ATT_IN_NBLK;
122     vattrbname = VAR_NATTRIB;
123     break;
124   case EX_EDGE_BLOCK:
125     dnumobjent = DIM_NUM_ED_IN_EBLK(obj_id_ndx);
126     dnumobjatt = DIM_NUM_ATT_IN_EBLK(obj_id_ndx);
127     vattrbname = VAR_EATTRIB(obj_id_ndx);
128     break;
129   case EX_FACE_BLOCK:
130     dnumobjent = DIM_NUM_FA_IN_FBLK(obj_id_ndx);
131     dnumobjatt = DIM_NUM_ATT_IN_FBLK(obj_id_ndx);
132     vattrbname = VAR_FATTRIB(obj_id_ndx);
133     break;
134   case EX_ELEM_BLOCK:
135     dnumobjent = DIM_NUM_EL_IN_BLK(obj_id_ndx);
136     dnumobjatt = DIM_NUM_ATT_IN_BLK(obj_id_ndx);
137     vattrbname = VAR_ATTRIB(obj_id_ndx);
138     break;
139   default:
140     snprintf(errmsg, MAX_ERR_LENGTH,
141              "Internal ERROR: unrecognized object type in switch: %d in file id %d", obj_type,
142              exoid);
143     ex_err_fn(exoid, __func__, errmsg, EX_BADPARAM);
144     EX_FUNC_LEAVE(EX_FATAL); /* number of attributes not defined */
145   }
146 
147   /* inquire id's of previously defined dimensions  */
148   if (ex__get_dimension(exoid, dnumobjent, "entries", &num_entries_this_obj, &temp, __func__) !=
149       NC_NOERR) {
150     EX_FUNC_LEAVE(EX_FATAL);
151   }
152 
153   if (start_num + num_ent - 1 > num_entries_this_obj) {
154     snprintf(errmsg, MAX_ERR_LENGTH,
155              "ERROR: start index (%" PRId64 ") + count (%" PRId64
156              ") is larger than total number of entities (%zu) in file id %d",
157              start_num, num_ent, num_entries_this_obj, exoid);
158     ex_err_fn(exoid, __func__, errmsg, EX_BADPARAM);
159     EX_FUNC_LEAVE(EX_FATAL);
160   }
161 
162   if (ex__get_dimension(exoid, dnumobjatt, "attributes", &num_attr, &temp, __func__) != NC_NOERR) {
163     EX_FUNC_LEAVE(EX_FATAL);
164   }
165 
166   if ((status = nc_inq_varid(exoid, vattrbname, &attrid)) != NC_NOERR) {
167     snprintf(errmsg, MAX_ERR_LENGTH,
168              "ERROR: failed to locate attributes for %s %" PRId64 " in file id %d",
169              ex_name_of_object(obj_type), obj_id, exoid);
170     ex_err_fn(exoid, __func__, errmsg, status);
171     EX_FUNC_LEAVE(EX_FATAL);
172   }
173 
174   /* read in the attributes */
175   start[0] = start_num - 1;
176   start[1] = 0;
177 
178   count[0] = num_ent;
179   count[1] = num_attr;
180   if (count[0] == 0) {
181     start[0] = 0;
182   }
183 
184   if (ex__comp_ws(exoid) == 4) {
185     status = nc_get_vara_float(exoid, attrid, start, count, attrib);
186   }
187   else {
188     status = nc_get_vara_double(exoid, attrid, start, count, attrib);
189   }
190 
191   if (status != NC_NOERR) {
192     snprintf(errmsg, MAX_ERR_LENGTH,
193              "ERROR: failed to get attributes for %s %" PRId64 " in file id %d",
194              ex_name_of_object(obj_type), obj_id, exoid);
195     ex_err_fn(exoid, __func__, errmsg, status);
196     EX_FUNC_LEAVE(EX_FATAL);
197   }
198   EX_FUNC_LEAVE(EX_NOERR);
199 }
200