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 * expsetp - ex_put_set_param
38 *
39 * entry conditions -
40 * input parameters:
41 * int exoid exodus file id
42 * int set_type the type of set
43 * int set_id set id
44 * int num_entries_in_set number of entries in the set
45 * int num_dist_fact_in_set number of distribution factors in the
46 * set
47 *
48 * exit conditions -
49 *
50 * revision history -
51 *
52 *
53 *****************************************************************************/
54
55 #include "exodusII.h"
56 #include "exodusII_int.h"
57
58 /*!
59 * writes the set id and the number of entries which describe a single set
60 * \param exoid exodus file id
61 * \param set_type the type of set
62 * \param set_id set id
63 * \param num_entries_in_set number of entries in the set
64 * \param num_dist_fact_in_set number of distribution factors in the set
65 */
66
ex_put_set_param(int exoid,ex_entity_type set_type,int set_id,int num_entries_in_set,int num_dist_fact_in_set)67 int ex_put_set_param (int exoid,
68 ex_entity_type set_type,
69 int set_id,
70 int num_entries_in_set,
71 int num_dist_fact_in_set)
72 {
73 int status;
74 size_t temp;
75 int dimid, varid, set_id_ndx, dims[1];
76 size_t start[1];
77 int num_sets;
78 int ldum;
79 int cur_num_sets, set_stat;
80 char errmsg[MAX_ERR_LENGTH];
81 char* dimptr = NULL;
82 char* idsptr = NULL;
83 char* statptr = NULL;
84 char* numentryptr = NULL;
85 char* numdfptr = NULL;
86 char* factptr = NULL;
87 char* entryptr = NULL;
88 char* extraptr = NULL;
89
90 exerrval = 0; /* clear error code */
91
92 /* setup pointers based on set_type
93 NOTE: there is another block that sets more stuff later ... */
94 if (set_type == EX_NODE_SET) {
95 dimptr = DIM_NUM_NS;
96 idsptr = VAR_NS_IDS;
97 statptr = VAR_NS_STAT;
98 }
99 else if (set_type == EX_EDGE_SET) {
100 dimptr = DIM_NUM_ES;
101 idsptr = VAR_ES_IDS;
102 statptr = VAR_ES_STAT;
103 }
104 else if (set_type == EX_FACE_SET) {
105 dimptr = DIM_NUM_FS;
106 idsptr = VAR_FS_IDS;
107 statptr = VAR_FS_STAT;
108 }
109 else if (set_type == EX_SIDE_SET) {
110 dimptr = DIM_NUM_SS;
111 idsptr = VAR_SS_IDS;
112 statptr = VAR_SS_STAT;
113 }
114 else if (set_type == EX_ELEM_SET) {
115 dimptr = DIM_NUM_ELS;
116 idsptr = VAR_ELS_IDS;
117 statptr = VAR_ELS_STAT;
118 }
119 else {
120 exerrval = EX_FATAL;
121 sprintf(errmsg,
122 "Error: invalid set type (%d)", set_type);
123 ex_err("ex_put_set_param",errmsg,exerrval);
124 return (EX_FATAL);
125 }
126
127 /* first check if any of that set type is specified */
128
129 if ((status = nc_inq_dimid(exoid, dimptr, &dimid)) != NC_NOERR) {
130 exerrval = status;
131 sprintf(errmsg,
132 "Error: no %ss specified in file id %d", ex_name_of_object(set_type),
133 exoid);
134 ex_err("ex_put_set_param",errmsg,exerrval);
135 return (EX_FATAL);
136 }
137
138 /* Check for duplicate set id entry */
139 ex_id_lkup(exoid, set_type, set_id);
140 if (exerrval != EX_LOOKUPFAIL) { /* found the side set id */
141 sprintf(errmsg,
142 "Error: %s %d already defined in file id %d", ex_name_of_object(set_type),
143 set_id,exoid);
144 ex_err("ex_put_set_param",errmsg,exerrval);
145 return(EX_FATAL);
146 }
147
148 /* Get number of sets specified for this file */
149 if ((status = nc_inq_dimlen(exoid,dimid,&temp)) != NC_NOERR) {
150 exerrval = status;
151 sprintf(errmsg,
152 "Error: failed to get number of %ss in file id %d",
153 ex_name_of_object(set_type), exoid);
154 ex_err("ex_put_set_param",errmsg,exerrval);
155 return (EX_FATAL);
156 }
157 num_sets = temp;
158
159
160 /* Keep track of the total number of sets defined using a counter stored
161 in a linked list keyed by exoid.
162 NOTE: ex_get_file_item finds the maximum number of sets defined
163 for a specific file and returns that value.
164 */
165 cur_num_sets=ex_get_file_item(exoid, ex_get_counter_list(set_type));
166 if (cur_num_sets >= num_sets) {
167 exerrval = EX_FATAL;
168 sprintf(errmsg,
169 "Error: exceeded number of %ss (%d) defined in file id %d",
170 ex_name_of_object(set_type), num_sets,exoid);
171 ex_err("ex_put_set_param",errmsg,exerrval);
172 return (EX_FATAL);
173 }
174
175 /* NOTE: ex_inc_file_item finds the current number of sets defined
176 for a specific file and returns that value incremented. */
177
178 cur_num_sets=ex_inc_file_item(exoid, ex_get_counter_list(set_type));
179 set_id_ndx = cur_num_sets + 1;
180
181 /* setup more pointers based on set_type */
182 if (set_type == EX_NODE_SET) {
183 numentryptr = DIM_NUM_NOD_NS(set_id_ndx);
184 entryptr = VAR_NODE_NS(set_id_ndx);
185 extraptr = NULL;
186 /* note we are using DIM_NUM_NODE_NS instead of DIM_NUM_DF_NS */
187 numdfptr = DIM_NUM_NOD_NS(set_id_ndx);
188 factptr = VAR_FACT_NS(set_id_ndx);
189 }
190 else if (set_type == EX_EDGE_SET) {
191 numentryptr = DIM_NUM_EDGE_ES(set_id_ndx);
192 entryptr = VAR_EDGE_ES(set_id_ndx);
193 extraptr = VAR_ORNT_ES(set_id_ndx);
194 numdfptr = DIM_NUM_DF_ES(set_id_ndx);
195 factptr = VAR_FACT_ES(set_id_ndx);
196 }
197 else if (set_type == EX_FACE_SET) {
198 numentryptr = DIM_NUM_FACE_FS(set_id_ndx);
199 entryptr = VAR_FACE_FS(set_id_ndx);
200 extraptr = VAR_ORNT_FS(set_id_ndx);
201 numdfptr = DIM_NUM_DF_FS(set_id_ndx);
202 factptr = VAR_FACT_FS(set_id_ndx);
203 }
204 else if (set_type == EX_SIDE_SET) {
205 numentryptr = DIM_NUM_SIDE_SS(set_id_ndx);
206 entryptr = VAR_ELEM_SS(set_id_ndx);
207 extraptr = VAR_SIDE_SS(set_id_ndx);
208 numdfptr = DIM_NUM_DF_SS(set_id_ndx);
209 factptr = VAR_FACT_SS(set_id_ndx);
210 }
211 if (set_type == EX_ELEM_SET) {
212 numentryptr = DIM_NUM_ELE_ELS(set_id_ndx);
213 entryptr = VAR_ELEM_ELS(set_id_ndx);
214 extraptr = NULL;
215 numdfptr = DIM_NUM_DF_ELS(set_id_ndx);
216 factptr = VAR_FACT_ELS(set_id_ndx);
217 }
218
219 /* write out information to previously defined variable */
220
221 /* first: get id of set id variable */
222 if ((status = nc_inq_varid(exoid, idsptr, &varid)) != NC_NOERR) {
223 exerrval = status;
224 sprintf(errmsg,
225 "Error: failed to locate %s %d in file id %d", ex_name_of_object(set_type),
226 set_id, exoid);
227 ex_err("ex_put_set_param",errmsg,exerrval);
228 return (EX_FATAL);
229 }
230
231 /* write out set id */
232 start[0] = cur_num_sets;
233
234 ldum = (int)set_id;
235 if ((status = nc_put_var1_int(exoid, varid, start, &ldum)) != NC_NOERR) {
236 exerrval = status;
237 sprintf(errmsg,
238 "Error: failed to store %s id %d in file id %d", ex_name_of_object(set_type),
239 set_id, exoid);
240 ex_err("ex_put_set_param",errmsg,exerrval);
241 return (EX_FATAL);
242 }
243
244 if (num_entries_in_set == 0) /* Is this a NULL set? */
245 set_stat = 0; /* change set status to NULL */
246 else
247 set_stat = 1; /* change set status to TRUE */
248
249 if ((status = nc_inq_varid(exoid, statptr, &varid)) != NC_NOERR) {
250 exerrval = status;
251 sprintf(errmsg,
252 "Error: failed to locate %s status in file id %d", ex_name_of_object(set_type),
253 exoid);
254 ex_err("ex_put_set_param",errmsg,exerrval);
255 return (EX_FATAL);
256 }
257
258 ldum = (int)set_stat;
259 if ((status = nc_put_var1_int(exoid, varid, start, &ldum)) != NC_NOERR) {
260 exerrval = status;
261 sprintf(errmsg,
262 "Error: failed to store %s %d status to file id %d", ex_name_of_object(set_type),
263 set_id, exoid);
264 ex_err("ex_put_set_param",errmsg,exerrval);
265 return (EX_FATAL);
266 }
267
268 if (num_entries_in_set == 0) {/* Is this a NULL set? */
269 return(EX_NOERR);
270 }
271
272 /* put netcdf file into define mode */
273 if ((status = nc_redef (exoid)) != NC_NOERR) {
274 exerrval = status;
275 sprintf(errmsg,
276 "Error: failed to put file id %d into define mode",
277 exoid);
278 ex_err("ex_put_set_param",errmsg,exerrval);
279 return (EX_FATAL);
280 }
281
282
283 /* define dimensions and variables */
284 if ((status = nc_def_dim(exoid, numentryptr,
285 num_entries_in_set, &dimid)) != NC_NOERR) {
286 exerrval = status;
287 if (status == NC_ENAMEINUSE)
288 {
289 sprintf(errmsg,
290 "Error: %s %d size already defined in file id %d",
291 ex_name_of_object(set_type), set_id,exoid);
292 ex_err("ex_put_set_param",errmsg,exerrval);
293 }
294 else {
295 sprintf(errmsg,
296 "Error: failed to define number of entries in %s %d in file id %d",
297 ex_name_of_object(set_type), set_id,exoid);
298 ex_err("ex_put_set_param",errmsg,exerrval);
299 }
300 goto error_ret;
301 }
302
303 /* create variable array in which to store the entry lists */
304
305 dims[0] = dimid;
306 if ((status = nc_def_var(exoid, entryptr, NC_INT, 1, dims, &varid)) != NC_NOERR) {
307 exerrval = status;
308 if (status == NC_ENAMEINUSE) {
309 sprintf(errmsg,
310 "Error: entry list already exists for %s %d in file id %d",
311 ex_name_of_object(set_type), set_id,exoid);
312 ex_err("ex_put_set_param",errmsg,exerrval);
313 } else {
314 sprintf(errmsg,
315 "Error: failed to create entry list for %s %d in file id %d",
316 ex_name_of_object(set_type), set_id,exoid);
317 ex_err("ex_put_set_param",errmsg,exerrval);
318 }
319 goto error_ret; /* exit define mode and return */
320 }
321
322 if (extraptr) {
323 if ((status = nc_def_var(exoid, extraptr, NC_INT, 1, dims, &varid)) != NC_NOERR) {
324 exerrval = status;
325 if (status == NC_ENAMEINUSE) {
326 sprintf(errmsg,
327 "Error: extra list already exists for %s %d in file id %d",
328 ex_name_of_object(set_type), set_id, exoid);
329 ex_err("ex_put_set_param",errmsg,exerrval);
330 } else {
331 sprintf(errmsg,
332 "Error: failed to create extra list for %s %d in file id %d",
333 ex_name_of_object(set_type), set_id,exoid);
334 ex_err("ex_put_set_param",errmsg,exerrval);
335 }
336 goto error_ret; /* exit define mode and return */
337
338 }
339 }
340
341 /* Create distribution factors variable if required */
342
343 if (num_dist_fact_in_set > 0) {
344
345 if (set_type == EX_NODE_SET) {
346 /* but num_dist_fact_in_set must equal number of nodes */
347 if (num_dist_fact_in_set != num_entries_in_set) {
348 exerrval = EX_FATAL;
349 sprintf(errmsg,
350 "Error: # dist fact (%d) not equal to # nodes (%d) in node set %d file id %d",
351 num_dist_fact_in_set, num_entries_in_set, set_id, exoid);
352 ex_err("ex_put_set_param",errmsg,exerrval);
353 goto error_ret; /* exit define mode and return */
354 }
355
356 /* resuse dimid from entry lists */
357
358 } else {
359 if ((status = nc_def_dim(exoid, numdfptr,
360 num_dist_fact_in_set, &dimid)) != NC_NOERR) {
361 exerrval = status;
362 sprintf(errmsg,
363 "Error: failed to define number of dist factors in %s %d in file id %d",
364 ex_name_of_object(set_type), set_id,exoid);
365 ex_err("ex_put_set_param",errmsg,exerrval);
366 goto error_ret; /* exit define mode and return */
367 }
368 }
369
370 /* create variable array in which to store the set distribution factors
371 */
372 dims[0] = dimid;
373 if ((status = nc_def_var(exoid, factptr, nc_flt_code(exoid), 1, dims, &varid)) != NC_NOERR) {
374 exerrval = status;
375 if (status == NC_ENAMEINUSE) {
376 sprintf(errmsg,
377 "Error: dist factors list already exists for %s %d in file id %d",
378 ex_name_of_object(set_type), set_id,exoid);
379 ex_err("ex_put_set_param",errmsg,exerrval);
380 } else {
381 sprintf(errmsg,
382 "Error: failed to create dist factors list for %s %d in file id %d",
383 ex_name_of_object(set_type), set_id,exoid);
384 ex_err("ex_put_set_param",errmsg,exerrval);
385 }
386 goto error_ret; /* exit define mode and return */
387 }
388 }
389
390 /* leave define mode */
391 if ((status = nc_enddef (exoid)) != NC_NOERR) {
392 exerrval = status;
393 sprintf(errmsg,
394 "Error: failed to complete definition in file id %d", exoid);
395 ex_err("ex_put_set_param",errmsg,exerrval);
396 return (EX_FATAL);
397 }
398
399 return (EX_NOERR);
400
401 /* Fatal error: exit definition mode and return */
402 error_ret:
403 if (nc_enddef (exoid) != NC_NOERR) { /* exit define mode */
404 sprintf(errmsg,
405 "Error: failed to complete definition for file id %d",
406 exoid);
407 ex_err("ex_put_set_param",errmsg,exerrval);
408 }
409 return (EX_FATAL);
410 }
411