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