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,int * cf_ids,void * pt_coordinates,char * tags)116  int ex_get_coordinate_frames( int exoid, int *nframes, int *cf_ids, void* pt_coordinates,
117              char* tags)
118 
119 {
120   int status;
121   int dimid; /* ID of the dimension of # frames */
122   char errmsg[MAX_ERR_LENGTH];
123   int varids;                      /* variable id for the frame ids  */
124   size_t start=0;                /* start value for varputs        */
125   size_t count;                  /* number vars to put in varput   */
126 
127   /* get the dimensions */
128   assert( nframes !=NULL );
129   status = nc_inq_dimid(exoid, DIM_NUM_CFRAMES, &dimid);
130   if (status != NC_NOERR){
131     *nframes=0;
132     return EX_NOERR;
133   }
134 
135   nc_inq_dimlen(exoid,dimid,&count);
136   *nframes=(int)count;
137 
138   if ( count==0 )
139     return (EX_NOERR);
140 
141   if ( cf_ids )
142     if ((status = nc_inq_varid(exoid,VAR_FRAME_IDS, &varids))!= NC_NOERR  ||
143   (nc_get_var_int(exoid,varids,cf_ids)!= NC_NOERR)) {
144       exerrval = status;
145       sprintf(errmsg,
146               "Error: failed to read number coordinate ids from file id %d",
147               exoid);
148       ex_err(PROCNAME,errmsg,exerrval);
149       return (EX_FATAL);
150     }
151 
152   if ( tags )
153     if ( (status = nc_inq_varid(exoid,VAR_FRAME_TAGS,&varids))!= NC_NOERR  ||
154          (nc_get_vara_text(exoid,varids,&start,&count,tags) != NC_NOERR)) {
155       exerrval = status;
156       sprintf(errmsg,
157               "Error: failed to read number coordinate tags from file id %d",
158               exoid);
159       ex_err(PROCNAME,errmsg,exerrval);
160       return (EX_FATAL);
161     }
162 
163   if (pt_coordinates ){
164     if ( (status = nc_inq_varid(exoid,VAR_FRAME_COORDS,&varids))!= NC_NOERR) {
165       exerrval = status;
166       sprintf(errmsg,
167               "Error: failed to read number coordinate tags from file id %d",
168               exoid);
169       ex_err(PROCNAME,errmsg,exerrval);
170       return (EX_FATAL);
171     }
172 
173     if (ex_comp_ws(exoid) == 4) {
174       status = nc_get_var_float(exoid,varids,pt_coordinates);
175     } else {
176       status = nc_get_var_double(exoid,varids,pt_coordinates);
177     }
178 
179     if (status != NC_NOERR) {
180       exerrval = status;
181       sprintf(errmsg,
182               "Error: failed to read number coordinate tags from file id %d",
183               exoid);
184       ex_err(PROCNAME,errmsg,exerrval);
185       return (EX_FATAL);
186     }
187   }
188 
189   return (EX_NOERR);
190 }
191