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 #include "exodusII.h"
37 #include "exodusII_int.h"
38 
39 /*!
40 The function ex_get_coord() reads the nodal coordinates of the
41 nodes. Memory must be allocated for the coordinate arrays (\c x_coor,
42 \c y_coor, and \c z_coor) before this call is made. The length of each
43 of these arrays is the number of nodes in the mesh.
44 
45 Because the coordinates are floating point values, the application
46 code must declare the arrays passed to be the appropriate type
47 (\c float or \c double) to match the compute word size passed in
48 ex_create() or ex_open().
49 
50 \return
51 In case of an error, ex_get_coord() returns a negative number;
52 a warning will return a positive number. Possible causes of errors
53 include:
54   -  data file not properly opened with call to ex_create() or ex_open()
55   -  a warning value is returned if nodal coordinates were not stored.
56 
57 \param[in]   exoid    exodus file ID returned from a previous call to ex_create() or ex_open().
58 \param[out]  x_coor   Returned X coordinates of the nodes. If this is \c NULL, the
59                       X-coordinates will not be read.
60 \param[out]  y_coor   Returned Y coordinates of the nodes. These are returned only if
61                       \c num_dim > 1; otherwise, pass in \c NULL. If this
62           is \c NULL, the Y-coordinates will not be read.
63 \param[out]  z_coor   Returned Z coordinates of the nodes. These are returned only if
64                       \c num_dim > 2; otherwise, pass in \c NULL. If this
65                       is \c NULL, the Z-coordinates will not be read.
66 
67 The following code segment will read the nodal coordinates
68 from an open exodus file :
69 
70 \code
71 int error, exoid;
72 
73 double *x, *y, *z;
74 
75 \comment{read nodal coordinates values from database}
76 x = (double *)calloc(num_nodes, sizeof(double));
77 y = (double *)calloc(num_nodes, sizeof(double));
78 if (num_dim >= 3)
79    z = (double *)calloc(num_nodes, sizeof(double));
80 else
81    z = 0;
82 
83 error = ex_get_coord(exoid, x, y, z);
84 
85 \comment{Do the same as the previous call in three separate calls}
86 error = ex_get_coord(exoid, x,    NULL, NULL);
87 error = ex_get_coord(exoid, NULL, y,    NULL);
88 if (num_dim >= 3)
89    error = ex_get_coord(exoid, NULL, NULL, z);
90 \endcode
91 
92 */
93 
ex_get_coord(int exoid,void * x_coor,void * y_coor,void * z_coor)94 int ex_get_coord (int exoid,
95                   void *x_coor,
96                   void *y_coor,
97                   void *z_coor)
98 {
99   int status;
100   int coordid;
101   int coordidx, coordidy, coordidz;
102 
103   int numnoddim, ndimdim;
104   size_t num_nod, num_dim, start[2], count[2], i;
105   char errmsg[MAX_ERR_LENGTH];
106 
107   exerrval = 0;
108 
109   /* inquire id's of previously defined dimensions  */
110 
111   if (ex_get_dimension(exoid, DIM_NUM_DIM, "dimensions",
112            &num_dim, &ndimdim, "ex_get_coord") != NC_NOERR) {
113     return(EX_FATAL);
114   }
115 
116   if (nc_inq_dimid (exoid, DIM_NUM_NODES, &numnoddim) != NC_NOERR)
117     {
118       /* If not found, then this file is storing 0 nodes.
119          Return immediately */
120       return (EX_NOERR);
121     }
122 
123   if ((status = nc_inq_dimlen(exoid, numnoddim, &num_nod)) != NC_NOERR)
124     {
125       exerrval = status;
126       sprintf(errmsg,
127               "Error: failed to get number of nodes in file id %d",
128               exoid);
129       ex_err("ex_get_coord",errmsg,exerrval);
130       return (EX_FATAL);
131     }
132 
133   /* read in the coordinates  */
134   if (ex_large_model(exoid) == 0) {
135     if ((status = nc_inq_varid (exoid, VAR_COORD, &coordid)) != NC_NOERR) {
136       exerrval = status;
137       sprintf(errmsg,
138               "Error: failed to locate nodal coordinates in file id %d", exoid);
139       ex_err("ex_get_coord",errmsg,exerrval);
140       return (EX_FATAL);
141     }
142 
143     for (i=0; i<num_dim; i++) {
144       char *which;
145       start[0] = i;
146       start[1] = 0;
147 
148       count[0] = 1;
149       count[1] = num_nod;
150 
151       if (i == 0 && x_coor != NULL) {
152   which = "X";
153   if (ex_comp_ws(exoid) == 4) {
154     status = nc_get_vara_float(exoid, coordid, start, count, x_coor);
155   } else {
156     status = nc_get_vara_double(exoid, coordid, start, count, x_coor);
157   }
158       }
159       else if (i == 1 && y_coor != NULL) {
160   which = "Y";
161   if (ex_comp_ws(exoid) == 4) {
162     status = nc_get_vara_float(exoid, coordid, start, count, y_coor);
163   } else {
164     status = nc_get_vara_double(exoid, coordid, start, count, y_coor);
165   }
166       }
167       else if (i == 2 && z_coor != NULL) {
168   which = "Z";
169   if (ex_comp_ws(exoid) == 4) {
170     status = nc_get_vara_float(exoid, coordid, start, count, z_coor);
171   } else {
172     status = nc_get_vara_double(exoid, coordid, start, count, z_coor);
173   }
174       }
175 
176       if (status != NC_NOERR) {
177   exerrval = status;
178   sprintf(errmsg,
179     "Error: failed to get %s coord array in file id %d", which, exoid);
180   ex_err("ex_get_coord",errmsg,exerrval);
181   return (EX_FATAL);
182       }
183     }
184 
185   } else {
186     if ((status = nc_inq_varid (exoid, VAR_COORD_X, &coordidx)) != NC_NOERR) {
187       exerrval = status;
188       sprintf(errmsg,
189         "Error: failed to locate x nodal coordinates in file id %d", exoid);
190       ex_err("ex_get_coord",errmsg,exerrval);
191       return (EX_FATAL);
192     }
193 
194     if (num_dim > 1) {
195       if ((status = nc_inq_varid (exoid, VAR_COORD_Y, &coordidy)) != NC_NOERR) {
196   exerrval = status;
197   sprintf(errmsg,
198     "Error: failed to locate y nodal coordinates in file id %d", exoid);
199   ex_err("ex_get_coord",errmsg,exerrval);
200   return (EX_FATAL);
201       }
202     } else {
203       coordidy = 0;
204     }
205 
206     if (num_dim > 2) {
207       if ((status = nc_inq_varid (exoid, VAR_COORD_Z, &coordidz)) != NC_NOERR) {
208   exerrval = status;
209   sprintf(errmsg,
210     "Error: failed to locate z nodal coordinates in file id %d", exoid);
211   ex_err("ex_get_coord",errmsg,exerrval);
212   return (EX_FATAL);
213       }
214     } else {
215       coordidz = 0;
216     }
217 
218     /* write out the coordinates  */
219     for (i=0; i<num_dim; i++)
220       {
221         void *coor = NULL;
222         char *which = NULL;
223 
224         if (i == 0) {
225           coor = x_coor;
226           which = "X";
227           coordid = coordidx;
228         } else if (i == 1) {
229           coor = y_coor;
230           which = "Y";
231           coordid = coordidy;
232         } else if (i == 2) {
233           coor = z_coor;
234           which = "Z";
235           coordid = coordidz;
236         }
237 
238         if (coor != NULL && coordid != 0) {
239           if (ex_comp_ws(exoid) == 4) {
240             status = nc_get_var_float(exoid, coordid, coor);
241           } else {
242             status = nc_get_var_double(exoid, coordid, coor);
243           }
244 
245           if (status != NC_NOERR) {
246       exerrval = status;
247       sprintf(errmsg,
248         "Error: failed to get %s coord array in file id %d", which, exoid);
249       ex_err("ex_put_coord",errmsg,exerrval);
250       return (EX_FATAL);
251     }
252         }
253       }
254   }
255   return (EX_NOERR);
256 }
257