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