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 * exgfrm - ex_get_coordinate_frames: read coordinate frames
11 *
12 * entry conditions -
13 * input parameters:
14 * int exoid exodus file id
15 *
16 * NOTE:
17 * cf_ids, pt_coordinates and tags may all be NULL, otherwise, they
18 * must have sufficient memory to store the output data. Two calls
19 * to this routine are anticipated (one to get nframes, the second
20 * to fill the data. i.e.
21 * ex_get_coordinate_frames(exoid,&nframes,0,0,0);
22 * ... allocate memory ...
23 * ex_get_coordinate_frames(exoid,&nframe,id,coords,tags);
24 *
25 *
26 * output conditions -
27 * int* nframes number of coordinate frames in model
28 * const int* cf_ids coordinate ids
29 * dimension int[nframes]
30 * const void* pt_coordinates pointer to coordinates. 9 values per
31 * coordinate frame
32 * dimension float[9*nframes]
33 * const char* tags character tag for each frame.
34 * 'r' - rectangular
35 * 'c' - cylindrical
36 * 's' - spherical
37 * dimension char[nframes]
38 *
39 * returns -
40 * EX_NOERR for no error
41 * EX_FATAL for fatal errors
42 *
43 *****************************************************************************/
44
45 #include "exodusII.h" // for ex_err, etc
46 #include "exodusII_int.h" // for EX_FATAL, EX_NOERR, etc
47
48 /*!
49 * Coordinate frames are stored in the database as a series of three
50 * points (defined in the basic cartesian coordinate system). The
51 * first of these points describes the origin of the new system. The
52 * second point lies on the 3 axis (or Z axis) of the frame. The third
53 * point is in the 1-3 (xz) plane. Each coordinate frame is identified
54 * by a unique, integer coordinate ID, and by a character tag
55 * indicating whether the frame is rectangular cartesian
56 * "R", cylindrical "C, or spherical "S".
57 * Because the coordinates are floating point values,
58 * the application code must declare the arrays passed to be the
59 * appropriate type "float" or "double" to match the
60 * compute word size passed in ex_create() or
61 * ex_open().
62 * \param exoid exodus file id
63 * \param[in,out] nframes if 'cf_ids' is NULL, then nframes is returned with
64 * the number
65 * of defined coordinate frames. Else it is the number of
66 * coordinate
67 * frames to read.
68 * \param[out] cf_ids The (nframes) coordinate frame Ids. If cf_ids is
69 * NULL, no data will be returned in this or any other array.
70 * Only
71 * nframes will be modified. Otherwise, space must be
72 * allocated to
73 * store 'nframes' integers before making this call.
74 * \param[out] pt_coordinates The (9*nframes) coordinates of the three
75 * points defining each coordinate axis. The first
76 * three values are
77 * the origin of the first frame. The next three
78 * values are the
79 * coordinates of a point on the 3rd axis of the
80 * first frame. The next
81 * three values are the coordinates of a point in the
82 * plane of the 1-3
83 * axis. The pattern is repeated for each frame. If
84 * 'cf_ids'
85 * is null, no data will be returned in this array.
86 * Otherwise, space
87 * must be allocated for 9*nframes floating point
88 * values. The size of
89 * the allocation depends upon the compute word size.
90 * \param[out] tags The (nframes) character tags associated with each
91 * coordinate frame. If 'cf_ids' is NULL, no data will be
92 * returned in this array. Otherwise, space must be allocated
93 * for
94 * 'nframes' characters.
95 */
96
ex_get_coordinate_frames(int exoid,int * nframes,void_int * cf_ids,void * pt_coordinates,char * tags)97 int ex_get_coordinate_frames(int exoid, int *nframes, void_int *cf_ids, void *pt_coordinates,
98 char *tags)
99
100 {
101 int status;
102 int dimid; /* ID of the dimension of # frames */
103 char errmsg[MAX_ERR_LENGTH];
104 int varids; /* variable id for the frame ids */
105 size_t start = 0; /* start value for varputs */
106 size_t count = 0; /* number vars to put in varput */
107
108 EX_FUNC_ENTER();
109 if (ex__check_valid_file_id(exoid, __func__) == EX_FATAL) {
110 EX_FUNC_LEAVE(EX_FATAL);
111 }
112
113 /* get the dimensions */
114 assert(nframes != NULL);
115 status = nc_inq_dimid(exoid, DIM_NUM_CFRAMES, &dimid);
116 if (status != NC_NOERR) {
117 *nframes = 0;
118 EX_FUNC_LEAVE(EX_NOERR);
119 }
120
121 (void)nc_inq_dimlen(exoid, dimid, &count);
122 *nframes = (int)count;
123
124 if (count == 0) {
125 EX_FUNC_LEAVE(EX_NOERR);
126 }
127
128 if (cf_ids) {
129 if ((status = nc_inq_varid(exoid, VAR_FRAME_IDS, &varids)) != NC_NOERR) {
130 snprintf(errmsg, MAX_ERR_LENGTH,
131 "ERROR: failed to read number coordinate ids from file id %d", exoid);
132 ex_err_fn(exoid, __func__, errmsg, status);
133 EX_FUNC_LEAVE(EX_FATAL);
134 }
135
136 if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
137 status = nc_get_var_longlong(exoid, varids, cf_ids);
138 }
139 else {
140 status = nc_get_var_int(exoid, varids, cf_ids);
141 }
142
143 if (status != NC_NOERR) {
144 snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to read coordinate frame ids from file id %d",
145 exoid);
146 ex_err_fn(exoid, __func__, errmsg, status);
147 EX_FUNC_LEAVE(EX_FATAL);
148 }
149 }
150
151 if (tags) {
152 if ((status = nc_inq_varid(exoid, VAR_FRAME_TAGS, &varids)) != NC_NOERR ||
153 (nc_get_vara_text(exoid, varids, &start, &count, tags) != NC_NOERR)) {
154 snprintf(errmsg, MAX_ERR_LENGTH,
155 "ERROR: failed to read number coordinate tags from file id %d", exoid);
156 ex_err_fn(exoid, __func__, errmsg, status);
157 EX_FUNC_LEAVE(EX_FATAL);
158 }
159 }
160
161 if (pt_coordinates) {
162 if ((status = nc_inq_varid(exoid, VAR_FRAME_COORDS, &varids)) != NC_NOERR) {
163 snprintf(errmsg, MAX_ERR_LENGTH,
164 "ERROR: failed to read number coordinate tags from file id %d", exoid);
165 ex_err_fn(exoid, __func__, errmsg, status);
166 EX_FUNC_LEAVE(EX_FATAL);
167 }
168
169 if (ex__comp_ws(exoid) == 4) {
170 status = nc_get_var_float(exoid, varids, pt_coordinates);
171 }
172 else {
173 status = nc_get_var_double(exoid, varids, pt_coordinates);
174 }
175
176 if (status != NC_NOERR) {
177 snprintf(errmsg, MAX_ERR_LENGTH,
178 "ERROR: failed to read number coordinate tags from file id %d", exoid);
179 ex_err_fn(exoid, __func__, errmsg, status);
180 EX_FUNC_LEAVE(EX_FATAL);
181 }
182 }
183
184 EX_FUNC_LEAVE(EX_NOERR);
185 }
186