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