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 *
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 <assert.h>
73 #include "exodusII.h"
74 #include "exodusII_int.h"
75 
76 /* -------------------- local defines --------------------------- */
77 #define PROCNAME "ex_get_coordinate_frames"
78 /* -------------------- end of local defines -------------------- */
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 the number
95  *                        of defined coordinate frames. Else it is the number of coordinate
96  *                        frames to read.
97  * \param[out] cf_ids The (nframes) coordinate frame Ids. If cf_ids is
98  *                    NULL, no data will be returned in this or any other array. Only
99  *                    nframes will be modified. Otherwise, space must be allocated to
100  *                    store 'nframes' integers before making this call.
101  * \param[out] pt_coordinates The (9*nframes) coordinates of the three
102  *                            points defining each coordinate axis. The first three values are
103  *                            the origin of the first frame. The next three values are the
104  *                            coordinates of a point on the 3rd axis of the first frame. The next
105  *                            three values are the coordinates of a point in the plane of the 1-3
106  *                            axis. The pattern is repeated for each frame. If 'cf_ids'
107  *                            is null, no data will be returned in this array. Otherwise, space
108  *                            must be allocated for 9*nframes floating point values. The size of
109  *                            the allocation depends upon the compute word size.
110  * \param[out] tags The (nframes) character tags associated with each
111  *                  coordinate frame. If 'cf_ids' is NULL, no data will be
112  *                  returned in this array. Otherwise, space must be allocated for
113  *                  'nframes' characters.
114  */
115 
ex_get_coordinate_frames(int exoid,int * nframes,void_int * cf_ids,void * pt_coordinates,char * tags)116  int ex_get_coordinate_frames( int exoid,
117 			       int *nframes,
118 			       void_int *cf_ids,
119 			       void* pt_coordinates,
120 			       char* tags)
121 
122 {
123   int status;
124   int dimid; /* ID of the dimension of # frames */
125   char errmsg[MAX_ERR_LENGTH];
126   int varids;                      /* variable id for the frame ids  */
127   size_t start=0;                /* start value for varputs        */
128   size_t count;                  /* number vars to put in varput   */
129 
130   /* get the dimensions */
131   assert( nframes !=NULL );
132   status = nc_inq_dimid(exoid, DIM_NUM_CFRAMES, &dimid);
133   if (status != NC_NOERR){
134     *nframes=0;
135     return EX_NOERR;
136   }
137 
138   nc_inq_dimlen(exoid,dimid,&count);
139   *nframes=(int)count;
140 
141   if ( count==0 )
142     return (EX_NOERR);
143 
144   if ( cf_ids ) {
145     if ((status = nc_inq_varid(exoid,VAR_FRAME_IDS, &varids))!= NC_NOERR) {
146       exerrval = status;
147       sprintf(errmsg,
148               "Error: failed to read number coordinate ids from file id %d",
149               exoid);
150       ex_err(PROCNAME,errmsg,exerrval);
151       return (EX_FATAL);
152     }
153 
154     if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
155       status = nc_get_var_longlong(exoid,varids,cf_ids);
156     } else {
157       status = nc_get_var_int(exoid,varids,cf_ids);
158     }
159 
160     if (status != NC_NOERR) {
161       exerrval = status;
162       sprintf(errmsg,
163               "Error: failed to read coordinate frame ids from file id %d",
164               exoid);
165       ex_err(PROCNAME,errmsg,exerrval);
166       return (EX_FATAL);
167     }
168   }
169 
170   if ( tags )
171     if ( (status = nc_inq_varid(exoid,VAR_FRAME_TAGS,&varids))!= NC_NOERR  ||
172          (nc_get_vara_text(exoid,varids,&start,&count,tags) != NC_NOERR)) {
173       exerrval = status;
174       sprintf(errmsg,
175               "Error: failed to read number coordinate tags from file id %d",
176               exoid);
177       ex_err(PROCNAME,errmsg,exerrval);
178       return (EX_FATAL);
179     }
180 
181   if (pt_coordinates ){
182     if ( (status = nc_inq_varid(exoid,VAR_FRAME_COORDS,&varids))!= NC_NOERR) {
183       exerrval = status;
184       sprintf(errmsg,
185               "Error: failed to read number coordinate tags from file id %d",
186               exoid);
187       ex_err(PROCNAME,errmsg,exerrval);
188       return (EX_FATAL);
189     }
190 
191     if (ex_comp_ws(exoid) == 4) {
192       status = nc_get_var_float(exoid,varids,pt_coordinates);
193     } else {
194       status = nc_get_var_double(exoid,varids,pt_coordinates);
195     }
196 
197     if (status != NC_NOERR) {
198       exerrval = status;
199       sprintf(errmsg,
200               "Error: failed to read number coordinate tags from file id %d",
201               exoid);
202       ex_err(PROCNAME,errmsg,exerrval);
203       return (EX_FATAL);
204     }
205   }
206 
207   return (EX_NOERR);
208 }
209