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 * exgssn - ex_get_side_set_node_list
38 *
39 * entry conditions -
40 * input parameters:
41 * int exoid exodus file id
42 * int side_set_id side set id
43 *
44 * exit conditions -
45 * int *side_set_node_cnt_list returned array of number of nodes for
46 * side or face
47 * int *side_set_node_list array of nodes
48 *
49 * revision history -
50 *
51 *
52 *****************************************************************************/
53
54 #include <ctype.h>
55 #include <string.h>
56 #include <stdlib.h>
57 #include "exodusII.h"
58 #include "exodusII_int.h"
59 /*!
60 * This routine is designed to read the Exodus II V 2.0 side set side
61 * definition and return a ExodusI style side set node definition.
62 */
63
ex_get_side_set_node_list(int exoid,int side_set_id,int * side_set_node_cnt_list,int * side_set_node_list)64 int ex_get_side_set_node_list(int exoid,
65 int side_set_id,
66 int *side_set_node_cnt_list,
67 int *side_set_node_list)
68 {
69 size_t m;
70 int i, j;
71 int num_side_sets, num_elem_blks, num_df, ndim;
72 int tot_num_elem = 0, tot_num_ss_elem = 0, elem_num = 0;
73 int connect_offset, side_num, node_pos;
74 int *elem_blk_ids = NULL;
75 int *connect = NULL;
76 int *ss_elem_ndx = NULL;
77 int *ss_elem_node_ndx = NULL;
78 int *ss_parm_ndx = NULL;
79 int *side_set_elem_list = NULL;
80 int *side_set_side_list = NULL;
81 int elem_ctr, node_ctr, elem_num_pos;
82 int num_elem_in_blk, num_nodes_per_elem, num_attr;
83 float fdum;
84 char *cdum, elem_type[MAX_STR_LENGTH+1];
85
86 struct elem_blk_parm *elem_blk_parms;
87
88 /* side to node translation tables -
89 These tables are used to look up the side number based on the
90 first and second node in the side/face list. The side node order
91 is found in the original Exodus document, SAND87-2997. The element
92 node order is found in the ExodusII document, SAND92-2137. These
93 tables were generated by following the right-hand rule for determining
94 the outward normal.
95 */
96 /* triangle */
97 static int tri_table[3][3] = {
98 /* 1 2 3 side */
99 {1,2,4}, {2,3,5}, {3,1,6} /* nodes */
100 };
101
102 /* triangle 3d */
103 static int tri3_table[5][7] = {
104 /* 1 2 side */
105 {1,2,3,4,5,6,7}, {3,2,1,6,5,4,7}, /* nodes */
106 /* 3 4 5 side */
107 {1,2,4,0,0,0,0}, {2,3,5,0,0,0,0}, {3,1,6,0,0,0,0} /* nodes */
108 };
109
110 /* quad */
111 static int quad_table[4][3] = {
112 /* 1 2 3 4 side */
113 {1,2,5}, {2,3,6}, {3,4,7}, {4,1,8} /* nodes */
114 };
115
116 /* shell */
117 static int shell_table[6][8] = {
118 /* 1 2 side */
119 {1,2,3,4,5,6,7,8}, {1,4,3,2,8,7,6,5} , /* nodes */
120 /* 3 4 side */
121 {1,2,5,0,0,0,0,0}, {2,3,6,0,0,0,0,0} , /* nodes */
122 /* 5 6 side */
123 {3,4,7,0,0,0,0,0}, {4,1,8,0,0,0,0,0} /* nodes */
124 };
125
126 /* tetra */
127 static int tetra_table[4][6] = {
128 /* 1 2 3 4 side */
129 {1,2,4,5,9,8}, {2,3,4,6,10,9}, {1,4,3,8,10,7}, {1,3,2,7,6,5} /* nodes */
130 };
131
132 /* wedge */
133 static int wedge_table[5][8] = {
134 /* 1 2 3 side */
135 {1,2,5,4,7,11,13,10}, {2,3,6,5,8,12,14,11}, {1,4,6,3,10,15,12,9},
136 /* 4 5 side */
137 {1,3,2,0,9,8,7,0}, {4,5,6,0,13,14,15,0} /* nodes */
138 };
139
140 /* hex */
141 static int hex_table[6][9] = {
142 /* 1 2 side */
143 {1,2,6,5,9,14,17,13,26}, {2,3,7,6,10,15,18,14,25}, /* nodes */
144 /* 3 4 side */
145 {3,4,8,7,11,16,19,15,27}, {1,5,8,4,13,20,16,12,24}, /* nodes */
146 /* 5 6 side */
147 {1,4,3,2,12,11,10,9,22}, {5,6,7,8,17,18,19,20,23} /* nodes */
148 };
149
150 /* pyramid */
151 static int pyramid_table[5][8] = {
152 /* 1 2 3 side */
153 {1,2,5,0,6,11,10,0}, {2,3,5,0,7,12,11,0}, {3,4,5,0,8,13,12,0}, /* nodes */
154 /* 4 5 side */
155 {1,5,4,0,10,13,9,0}, {1,4,3,2,9,8,7,6} /* nodes */
156 };
157
158
159 char errmsg[MAX_ERR_LENGTH];
160
161 exerrval = 0; /* clear error code */
162
163 cdum = 0; /* initialize even though it is not used */
164
165 /* first check if any side sets are specified */
166 /* inquire how many side sets have been stored */
167
168 if ((ex_inquire(exoid, EX_INQ_SIDE_SETS, &num_side_sets, &fdum, cdum)) == -1)
169 {
170 sprintf(errmsg,
171 "Error: failed to get number of side sets in file id %d",exoid);
172 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
173 return(EX_FATAL);
174 }
175
176 if (num_side_sets == 0)
177 {
178 sprintf(errmsg,
179 "Warning: no side sets defined in file id %d",exoid);
180 ex_err("ex_get_side_set_node_list",errmsg,EX_WARN);
181 return(EX_WARN);
182 }
183
184 /* Lookup index of side set id in VAR_SS_IDS array */
185
186 ex_id_lkup(exoid,EX_SIDE_SET,side_set_id);
187 if (exerrval != 0)
188 {
189 if (exerrval == EX_NULLENTITY)
190 {
191 sprintf(errmsg,
192 "Warning: side set %d is NULL in file id %d",
193 side_set_id,exoid);
194 ex_err("ex_get_side_set_node_list",errmsg,EX_MSG);
195 return (EX_WARN);
196 }
197 else
198 {
199
200 sprintf(errmsg,
201 "Error: failed to locate side set id %d in VAR_SS_IDS array in file id %d",
202 side_set_id,exoid);
203 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
204 return (EX_FATAL);
205 }
206 }
207
208 if ((ex_inquire(exoid, EX_INQ_ELEM_BLK, &num_elem_blks, &fdum, cdum)) == -1)
209 {
210 sprintf(errmsg,
211 "Error: failed to get number of element blocks in file id %d",exoid);
212 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
213 return(EX_FATAL);
214 }
215
216 if ((ex_inquire(exoid, EX_INQ_ELEM, &tot_num_elem, &fdum, cdum)) == -1)
217 {
218 sprintf(errmsg,
219 "Error: failed to get total number of elements in file id %d",exoid);
220 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
221 return(EX_FATAL);
222 }
223
224 /* get the dimensionality of the coordinates; this is necessary to
225 distinguish between 2d TRIs and 3d TRIs */
226
227 if ((ex_inquire(exoid, EX_INQ_DIM, &ndim, &fdum, cdum)) == -1)
228 {
229 sprintf(errmsg,
230 "Error: failed to get dimensionality in file id %d",exoid);
231 ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
232 return(EX_FATAL);
233 }
234
235 /* First determine the # of elements in the side set*/
236 if ((ex_get_side_set_param(exoid,side_set_id,&tot_num_ss_elem,&num_df)) == -1)
237 {
238 sprintf(errmsg,
239 "Error: failed to get number of elements in side set %d in file id %d",
240 side_set_id, exoid);
241 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
242 return(EX_FATAL);
243 }
244
245 /* Allocate space for the side set element list */
246 if (!(side_set_elem_list=malloc(tot_num_ss_elem*sizeof(int))))
247 {
248 exerrval = EX_MEMFAIL;
249 sprintf(errmsg,
250 "Error: failed to allocate space for side set element list for file id %d",
251 exoid);
252 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
253 return (EX_FATAL);
254 }
255
256 /* Allocate space for the side set side list */
257 if (!(side_set_side_list=malloc(tot_num_ss_elem*sizeof(int))))
258 {
259 free(side_set_elem_list);
260 exerrval = EX_MEMFAIL;
261 sprintf(errmsg,
262 "Error: failed to allocate space for side set side list for file id %d",
263 exoid);
264 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
265 return (EX_FATAL);
266 }
267
268 if (ex_get_side_set(exoid, side_set_id,
269 side_set_elem_list, side_set_side_list) == -1)
270 {
271 free(side_set_elem_list);
272 free(side_set_side_list);
273 sprintf(errmsg,
274 "Error: failed to get side set %d in file id %d",
275 side_set_id, exoid);
276 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
277 return (EX_FATAL);
278 }
279
280 /* Allocate space for the ss element index array */
281 if (!(ss_elem_ndx= malloc(tot_num_ss_elem*sizeof(int))))
282 {
283 free(side_set_elem_list);
284 free(side_set_side_list);
285 exerrval = EX_MEMFAIL;
286 sprintf(errmsg,
287 "Error: failed to allocate space for side set elem sort array for file id %d",
288 exoid);
289 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
290 return (EX_FATAL);
291 }
292
293 /* Sort side set element list into index array - non-destructive */
294 for (i=0;i<tot_num_ss_elem;i++)
295 ss_elem_ndx[i] = i; /* init index array to current position */
296
297 ex_iqsort(side_set_elem_list, ss_elem_ndx,tot_num_ss_elem);
298
299
300 /* Allocate space for the element block ids */
301 if (!(elem_blk_ids= malloc(num_elem_blks*sizeof(int))))
302 {
303 exerrval = EX_MEMFAIL;
304 free(ss_elem_ndx);
305 free(side_set_side_list);
306 free(side_set_elem_list);
307 sprintf(errmsg,
308 "Error: failed to allocate space for element block ids for file id %d",
309 exoid);
310 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
311 return (EX_FATAL);
312 }
313
314 if (ex_get_elem_blk_ids(exoid, elem_blk_ids) == -1)
315 {
316 free(elem_blk_ids);
317 free(ss_elem_ndx);
318 free(side_set_side_list);
319 free(side_set_elem_list);
320 sprintf(errmsg,
321 "Error: failed to get element block ids in file id %d",
322 exoid);
323 ex_err("ex_get_side_set_node_list",errmsg,EX_MSG);
324 return(EX_FATAL);
325 }
326
327 /* Allocate space for the element block params */
328 if (!(elem_blk_parms= malloc(num_elem_blks*sizeof(struct elem_blk_parm))))
329 {
330 free(elem_blk_ids);
331 free(ss_elem_ndx);
332 free(side_set_side_list);
333 free(side_set_elem_list);
334 exerrval = EX_MEMFAIL;
335 sprintf(errmsg,
336 "Error: failed to allocate space for element block params for file id %d",
337 exoid);
338 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
339 return (EX_FATAL);
340 }
341
342 elem_ctr = 0;
343 for (i=0; i<num_elem_blks; i++)
344 {
345 /* read in an element block parameter */
346 if ((ex_get_elem_block (exoid,
347 elem_blk_ids[i],
348 elem_type,
349 &num_elem_in_blk,
350 &num_nodes_per_elem,
351 &num_attr)) == -1)
352 {
353 free(elem_blk_parms);
354 free(elem_blk_ids);
355 free(ss_elem_ndx);
356 free(side_set_side_list);
357 free(side_set_elem_list);
358 sprintf(errmsg,
359 "Error: failed to get element block %d parameters in file id %d",
360 elem_blk_ids[i], exoid);
361 ex_err("ex_get_side_set_node_list",errmsg,EX_MSG);
362 return(EX_FATAL);
363 }
364
365 elem_blk_parms[i].num_elem_in_blk = num_elem_in_blk;
366 elem_blk_parms[i].num_nodes_per_elem = num_nodes_per_elem;
367 elem_blk_parms[i].num_attr = num_attr;
368
369 for (m=0; m < strlen(elem_type); m++)
370 elem_blk_parms[i].elem_type[m] = toupper(elem_type[m]);
371 elem_blk_parms[i].elem_type[m] = EX_EL_NULL_ELEMENT;
372
373 if (strncmp(elem_blk_parms[i].elem_type,"CIRCLE",3) == 0)
374 {
375 elem_blk_parms[i].elem_type_val = EX_EL_CIRCLE;
376 /* set side set node stride */
377 elem_blk_parms[i].num_nodes_per_side[0] = 1;
378 }
379 else if (strncmp(elem_blk_parms[i].elem_type,"SPHERE",3) == 0)
380 {
381 elem_blk_parms[i].elem_type_val = EX_EL_SPHERE;
382 /* set side set node stride */
383 elem_blk_parms[i].num_nodes_per_side[0] = 1;
384 }
385 else if (strncmp(elem_blk_parms[i].elem_type,"QUAD",3) == 0)
386 {
387 elem_blk_parms[i].elem_type_val = EX_EL_QUAD;
388 /* determine side set node stride */
389 if (elem_blk_parms[i].num_nodes_per_elem == 4)
390 elem_blk_parms[i].num_nodes_per_side[0] = 2;
391 else if (elem_blk_parms[i].num_nodes_per_elem == 5)
392 elem_blk_parms[i].num_nodes_per_side[0] = 2;
393 else
394 elem_blk_parms[i].num_nodes_per_side[0] = 3;
395 }
396 else if (strncmp(elem_blk_parms[i].elem_type,"TRIANGLE",3) == 0)
397 {
398 elem_blk_parms[i].elem_type_val = EX_EL_TRIANGLE;
399 /* set default side set node stride */
400 if (ndim == 2) /* 2d TRIs */
401 {
402 if (elem_blk_parms[i].num_nodes_per_elem == 3)
403 elem_blk_parms[i].num_nodes_per_side[0] = 2;
404 else
405 elem_blk_parms[i].num_nodes_per_side[0] = 3;
406 }
407 else if (ndim == 3) /* 3d TRIs */
408 {
409 if (elem_blk_parms[i].num_nodes_per_elem == 3)
410 elem_blk_parms[i].num_nodes_per_side[0] = 3;
411 else
412 elem_blk_parms[i].num_nodes_per_side[0] = 6;
413 }
414 }
415 else if (strncmp(elem_blk_parms[i].elem_type,"SHELL",3) == 0)
416 {
417 elem_blk_parms[i].elem_type_val = EX_EL_SHELL;
418 /* determine side set node stride */
419 if (elem_blk_parms[i].num_nodes_per_elem == 2) /* KLUDGE for 2D Shells*/
420 elem_blk_parms[i].num_nodes_per_side[0] = 2;
421 else if (elem_blk_parms[i].num_nodes_per_elem == 4)
422 elem_blk_parms[i].num_nodes_per_side[0] = 4;
423 else
424 elem_blk_parms[i].num_nodes_per_side[0] = 8;
425 }
426 else if (strncmp(elem_blk_parms[i].elem_type,"HEX",3) == 0)
427 {
428 elem_blk_parms[i].elem_type_val = EX_EL_HEX;
429 /* determine side set node stride */
430 if (elem_blk_parms[i].num_nodes_per_elem == 8) /* 8-node bricks */
431 elem_blk_parms[i].num_nodes_per_side[0] = 4;
432 else if (elem_blk_parms[i].num_nodes_per_elem == 9) /* 9-node bricks */
433 elem_blk_parms[i].num_nodes_per_side[0] = 4;
434 else if (elem_blk_parms[i].num_nodes_per_elem == 12) /* HEXSHELLS */
435 elem_blk_parms[i].num_nodes_per_side[0] = 4;
436 else if (elem_blk_parms[i].num_nodes_per_elem == 27) /* 27-node bricks */
437 elem_blk_parms[i].num_nodes_per_side[0] = 9;
438 else
439 elem_blk_parms[i].num_nodes_per_side[0] = 8;
440 }
441 else if (strncmp(elem_blk_parms[i].elem_type,"TETRA",3) == 0)
442 {
443 elem_blk_parms[i].elem_type_val = EX_EL_TETRA;
444 /* determine side set node stride */
445 if (elem_blk_parms[i].num_nodes_per_elem == 4)
446 elem_blk_parms[i].num_nodes_per_side[0] = 3;
447 else if (elem_blk_parms[i].num_nodes_per_elem == 8)
448 elem_blk_parms[i].num_nodes_per_side[0] = 4;
449 else
450 elem_blk_parms[i].num_nodes_per_side[0] = 6;
451 }
452 else if (strncmp(elem_blk_parms[i].elem_type,"WEDGE",3) == 0)
453 {
454 elem_blk_parms[i].elem_type_val = EX_EL_WEDGE;
455 /* determine side set node stride */
456 if (elem_blk_parms[i].num_nodes_per_elem == 6)
457 elem_blk_parms[i].num_nodes_per_side[0] = 4;
458 else
459 elem_blk_parms[i].num_nodes_per_side[0] = 8;
460 }
461 else if (strncmp(elem_blk_parms[i].elem_type,"PYRAMID",3) == 0)
462 {
463 elem_blk_parms[i].elem_type_val = EX_EL_PYRAMID;
464 /* determine side set node stride */
465 if (elem_blk_parms[i].num_nodes_per_elem == 5)
466 elem_blk_parms[i].num_nodes_per_side[0] = 4;
467 else
468 elem_blk_parms[i].num_nodes_per_side[0] = 8;
469 }
470 else if (strncmp(elem_blk_parms[i].elem_type,"BEAM",3) == 0)
471 {
472 elem_blk_parms[i].elem_type_val = EX_EL_BEAM;
473 /* determine side set node stride */
474 if (elem_blk_parms[i].num_nodes_per_elem == 2)
475 elem_blk_parms[i].num_nodes_per_side[0] = 2;
476 else
477 elem_blk_parms[i].num_nodes_per_side[0] = 3;
478 }
479 else if ( (strncmp(elem_blk_parms[i].elem_type,"TRUSS",3) == 0) ||
480 (strncmp(elem_blk_parms[i].elem_type,"BAR",3) == 0) ||
481 (strncmp(elem_blk_parms[i].elem_type,"EDGE",3) == 0) )
482 {
483 elem_blk_parms[i].elem_type_val = EX_EL_TRUSS;
484 /* determine side set node stride */
485 if (elem_blk_parms[i].num_nodes_per_elem == 2)
486 elem_blk_parms[i].num_nodes_per_side[0] = 2;
487 else
488 elem_blk_parms[i].num_nodes_per_side[0] = 3;
489 }
490 else if (strncmp(elem_blk_parms[i].elem_type,"NULL",3) == 0)
491 {
492 elem_blk_parms[i].elem_type_val = EX_EL_NULL_ELEMENT;
493 elem_blk_parms[i].num_nodes_per_side[0] = 0;
494 elem_blk_parms[i].num_elem_in_blk = 0;
495 }
496 else
497 { /* unsupported element type; no problem if no sides specified for
498 this element block */
499 elem_blk_parms[i].elem_type_val = EX_EL_UNK;
500 elem_blk_parms[i].num_nodes_per_side[0] = 0;
501 }
502 elem_blk_parms[i].elem_blk_id = elem_blk_ids[i]; /* save id */
503 elem_ctr += elem_blk_parms[i].num_elem_in_blk;
504 elem_blk_parms[i].elem_ctr = elem_ctr; /* save elem number max */
505 }
506
507
508 /* Allocate space for the ss element to element block parameter index array */
509 if (!(ss_parm_ndx=malloc(tot_num_ss_elem*sizeof(int))))
510 {
511 free(elem_blk_parms);
512 free(elem_blk_ids);
513 free(ss_elem_ndx);
514 free(side_set_side_list);
515 free(side_set_elem_list);
516 exerrval = EX_MEMFAIL;
517 sprintf(errmsg,
518 "Error: failed to allocate space for side set elem parms index for file id %d",
519 exoid);
520 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
521 return (EX_FATAL);
522 }
523
524
525 /* Allocate space for the ss element to node list index array */
526 if (!(ss_elem_node_ndx=malloc(tot_num_ss_elem*sizeof(int))))
527 {
528 free(ss_parm_ndx);
529 free(elem_blk_parms);
530 free(elem_blk_ids);
531 free(ss_elem_ndx);
532 free(side_set_side_list);
533 free(side_set_elem_list);
534 exerrval = EX_MEMFAIL;
535 sprintf(errmsg,
536 "Error: failed to allocate space for side set elem to node index for file id %d",
537 exoid);
538 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
539
540 return (EX_FATAL);
541 }
542
543 /* Build side set element to node list index and side set element
544 parameter index.
545 */
546 node_ctr = 0;
547 for (i=0;i<tot_num_ss_elem;i++) {
548 for (j=0; j<num_elem_blks; j++) {
549 if (elem_blk_parms[j].elem_type_val != EX_EL_NULL_ELEMENT)
550 if (side_set_elem_list[i] <= elem_blk_parms[j].elem_ctr)
551 break;
552 }
553
554 if (j >= num_elem_blks) {
555 exerrval = EX_BADPARAM;
556 sprintf(errmsg,
557 "Error: Invalid element number %d found in side set %d in file %d",
558 side_set_elem_list[i], side_set_id, exoid);
559 free(ss_parm_ndx);
560 free(ss_elem_node_ndx);
561 free(elem_blk_parms);
562 free(elem_blk_ids);
563 free(ss_elem_ndx);
564 free(side_set_side_list);
565 free(side_set_elem_list);
566 ex_err("ex_get_side_set_node_list",errmsg,EX_MSG);
567 return (EX_FATAL);
568 }
569
570 ss_parm_ndx[i] = j; /* assign parameter block index */
571 ss_elem_node_ndx[i] = node_ctr; /* assign node list index */
572
573 /* Update node_ctr (which points to next node in chain */
574
575 /* WEDGEs with 3 node sides (side 4 or 5) are special cases */
576 if (elem_blk_parms[j].elem_type_val == EX_EL_WEDGE &&
577 (side_set_side_list[i] == 4 || side_set_side_list[i] == 5))
578 {
579 if (elem_blk_parms[j].num_nodes_per_elem == 6)
580 node_ctr += 3; /* 3 node side */
581 else
582 node_ctr += 6; /* 6 node side */
583 }
584 /* PYRAMIDSs with 3 node sides (sides 1,2,3,4) are also special */
585 else if (elem_blk_parms[j].elem_type_val == EX_EL_PYRAMID &&
586 (side_set_side_list[i] < 5))
587 {
588 if (elem_blk_parms[j].num_nodes_per_elem == 5)
589 node_ctr += 3; /* 3 node side */
590 else
591 node_ctr += 6; /* 6 node side */
592 }
593 /* side numbers 3,4,5,6 for SHELLs are also special */
594 else if (elem_blk_parms[j].elem_type_val == EX_EL_SHELL &&
595 (side_set_side_list[i] > 2 ))
596 {
597 if (elem_blk_parms[j].num_nodes_per_elem == 4)
598 node_ctr += 2; /* 2 node side */
599 else
600 node_ctr += 3; /* 3 node side */
601 }
602 /* side numbers 3,4,5 for 3d TRIs are also special */
603 else if (elem_blk_parms[j].elem_type_val == EX_EL_TRIANGLE &&
604 ndim == 3 &&
605 side_set_side_list[i] > 2 )
606 {
607 if (elem_blk_parms[j].num_nodes_per_elem == 3) /* 3-node TRI */
608 node_ctr += 2; /* 2 node side */
609 else /* 6-node TRI */
610 node_ctr += 3; /* 3 node side */
611 }
612 else /* all other element types */
613 node_ctr += elem_blk_parms[j].num_nodes_per_side[0];
614 }
615
616 /* All setup, ready to go ... */
617
618 elem_ctr=0;
619
620 for (j=0; j < tot_num_ss_elem; j++) {
621
622 if (side_set_elem_list[ss_elem_ndx[j]] > elem_ctr) {
623 /* release connectivity array space and get next one */
624 if (elem_ctr > 0) {
625 free(connect);
626 }
627
628 /* Allocate space for the connectivity array for new element block */
629 if (!(connect=malloc(elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].num_elem_in_blk*
630 elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].num_nodes_per_elem*
631 (int)sizeof(int))))
632 {
633 free(elem_blk_parms);
634 free(elem_blk_ids);
635 free(ss_elem_ndx);
636 free(ss_elem_node_ndx);
637 free(ss_parm_ndx);
638 free(side_set_side_list);
639 free(side_set_elem_list);
640 exerrval = EX_MEMFAIL;
641 sprintf(errmsg,
642 "Error: failed to allocate space for connectivity array for file id %d",
643 exoid);
644 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
645 return (EX_FATAL);
646 }
647
648 /* get connectivity array */
649 if (ex_get_elem_conn(exoid,
650 elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id,
651 connect) == -1)
652 {
653 free(connect);
654 free(elem_blk_parms);
655 free(elem_blk_ids);
656 free(ss_elem_ndx);
657 free(ss_elem_node_ndx);
658 free(ss_parm_ndx);
659 free(side_set_side_list);
660 free(side_set_elem_list);
661 sprintf(errmsg,
662 "Error: failed to allocate space for connectivity array for file id %d",
663 exoid);
664 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
665 return (EX_FATAL);
666 }
667 elem_ctr = elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_ctr;
668 }
669 /* For each side in side set, use the appropriate lookup table to
670 determine the nodes from the connect array. */
671
672 elem_num = side_set_elem_list[ss_elem_ndx[j]]-1;/* element number 0-based*/
673 /* calculate the relative element number position in it's block*/
674
675 elem_num_pos = elem_num -
676 (elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_ctr -
677 elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].num_elem_in_blk);
678
679 /* calculate the beginning of the node list for this element by
680 using the ss_elem_node_ndx index into the side_sets_node_index
681 and adding the element number position * number of nodes per elem */
682
683 num_nodes_per_elem = elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].num_nodes_per_elem;
684 node_pos = ss_elem_node_ndx[ss_elem_ndx[j]];
685 connect_offset = num_nodes_per_elem*elem_num_pos;
686 side_num = side_set_side_list[ss_elem_ndx[j]]-1;
687
688 switch (elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_type_val)
689 {
690 case EX_EL_CIRCLE:
691 case EX_EL_SPHERE:
692 { /* Note: no side-node lookup table is used for this simple case */
693 side_set_node_list[node_pos] = connect[connect_offset];
694 side_set_node_cnt_list[ss_elem_ndx[j]] = 1; /* 1 node object */
695 break;
696 }
697 case EX_EL_TRUSS:
698 case EX_EL_BEAM:
699 { /* Note: no side-node lookup table is used for this simple case */
700 side_set_node_list[node_pos] = connect[connect_offset];
701 side_set_node_list[node_pos+1] = connect[connect_offset+1];
702 side_set_node_cnt_list[ss_elem_ndx[j]] = 2; /* 2 node object */
703 if (num_nodes_per_elem > 2)
704 {
705 side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */
706 side_set_node_list[node_pos+2] = connect[connect_offset+2];
707 }
708 break;
709 }
710 case EX_EL_TRIANGLE:
711 {
712 if (side_num+1 < 1 || side_num+1 > 5) /* side number range check */
713 {
714 exerrval = EX_BADPARAM;
715 sprintf(errmsg,
716 "Error: Invalid triangle edge number %d in file id %d",
717 side_num+1, exoid);
718 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
719 free(connect);
720 free(elem_blk_parms);
721 free(elem_blk_ids);
722 free(ss_elem_ndx);
723 free(ss_elem_node_ndx);
724 free(ss_parm_ndx);
725 free(side_set_side_list);
726 free(side_set_elem_list);
727 return(EX_FATAL);
728 }
729
730 if (ndim == 2) /* 2d TRIs */
731 {
732 side_set_node_list[node_pos] =
733 connect[connect_offset+tri_table[side_num][0]-1];
734 side_set_node_list[node_pos+1] =
735 connect[connect_offset+tri_table[side_num][1]-1];
736 side_set_node_cnt_list[ss_elem_ndx[j]] = 2; /* 2 node object */
737 if (num_nodes_per_elem > 3) /* 6-node TRI */
738 {
739 side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */
740 side_set_node_list[node_pos+2] =
741 connect[connect_offset+tri_table[side_num][2]-1];
742 }
743 }
744 else if (ndim == 3) /* 3d TRIs */
745 {
746 side_set_node_list[node_pos] =
747 connect[connect_offset+tri3_table[side_num][0]-1];
748 side_set_node_list[node_pos+1] =
749 connect[connect_offset+tri3_table[side_num][1]-1];
750 side_set_node_cnt_list[ss_elem_ndx[j]] = 2; /* 2 node object */
751 if (side_num+1 <= 2) /* 3- or 6-node face */
752 {
753 if (num_nodes_per_elem == 3) /* 3-node face */
754 {
755 side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */
756 side_set_node_list[node_pos+2] =
757 connect[connect_offset+tri3_table[side_num][2]-1];
758 }
759 else /* 6-node face */
760 {
761 side_set_node_cnt_list[ss_elem_ndx[j]] = 6; /* 6 node object */
762 side_set_node_list[node_pos+2] =
763 connect[connect_offset+tri3_table[side_num][2]-1];
764 side_set_node_list[node_pos+3] =
765 connect[connect_offset+tri3_table[side_num][3]-1];
766 side_set_node_list[node_pos+4] =
767 connect[connect_offset+tri3_table[side_num][4]-1];
768 side_set_node_list[node_pos+5] =
769 connect[connect_offset+tri3_table[side_num][5]-1];
770 }
771 }
772 else /* 2- or 3-node edge */
773 {
774 if (num_nodes_per_elem > 3) /* 3-node edge */
775 {
776 side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */
777 side_set_node_list[node_pos+2] =
778 connect[connect_offset+tri3_table[side_num][2]-1];
779 }
780 }
781 }
782 break;
783 }
784 case EX_EL_QUAD:
785 {
786 if (side_num+1 < 1 || side_num+1 > 4) /* side number range check */
787 {
788 exerrval = EX_BADPARAM;
789 sprintf(errmsg,
790 "Error: Invalid quad edge number %d in file id %d",
791 side_num+1, exoid);
792 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
793 free(connect);
794 free(elem_blk_parms);
795 free(elem_blk_ids);
796 free(ss_elem_ndx);
797 free(ss_elem_node_ndx);
798 free(ss_parm_ndx);
799 free(side_set_side_list);
800 free(side_set_elem_list);
801 return(EX_FATAL);
802 }
803
804 side_set_node_list[node_pos] =
805 connect[connect_offset+quad_table[side_num][0]-1];
806 side_set_node_list[node_pos+1] =
807 connect[connect_offset+quad_table[side_num][1]-1];
808 side_set_node_cnt_list[ss_elem_ndx[j]] = 2; /* 2 node object */
809 if (num_nodes_per_elem > 5)
810 {
811 side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */
812 side_set_node_list[node_pos+2] =
813 connect[connect_offset+quad_table[side_num][2]-1];
814 }
815 break;
816 }
817 case EX_EL_SHELL:
818 {
819 if (side_num+1 < 1 || side_num+1 > 6) /* side number range check */
820 {
821 exerrval = EX_BADPARAM;
822 sprintf(errmsg,
823 "Error: Invalid shell face number %d in file id %d",
824 side_num+1, exoid);
825 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
826 free(connect);
827 free(elem_blk_parms);
828 free(elem_blk_ids);
829 free(ss_elem_ndx);
830 free(ss_elem_node_ndx);
831 free(ss_parm_ndx);
832 free(side_set_side_list);
833 free(side_set_elem_list);
834 return(EX_FATAL);
835 }
836
837 side_set_node_list[node_pos] =
838 connect[connect_offset+shell_table[side_num][0]-1];
839 side_set_node_list[node_pos+1] =
840 connect[connect_offset+shell_table[side_num][1]-1];
841 side_set_node_cnt_list[ss_elem_ndx[j]] = 2; /* 2 node object */
842 if (num_nodes_per_elem > 2) /*** KLUDGE for 2D shells ***/
843 {
844 if (side_num+1 <= 2) /* 4-node face */
845 {
846 side_set_node_cnt_list[ss_elem_ndx[j]] = 4; /* 4 node object */
847 side_set_node_list[node_pos+2] =
848 connect[connect_offset+shell_table[side_num][2]-1];
849 side_set_node_list[node_pos+3] =
850 connect[connect_offset+shell_table[side_num][3]-1];
851 }
852 }
853 if (num_nodes_per_elem == 8)
854 {
855 if (side_num+1 <= 2) /* 8-node face */
856 {
857 side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node object */
858 side_set_node_list[node_pos+4] =
859 connect[connect_offset+shell_table[side_num][4]-1];
860 side_set_node_list[node_pos+5] =
861 connect[connect_offset+shell_table[side_num][5]-1];
862 side_set_node_list[node_pos+6] =
863 connect[connect_offset+shell_table[side_num][6]-1];
864 side_set_node_list[node_pos+7] =
865 connect[connect_offset+shell_table[side_num][7]-1];
866 }
867 else
868 {
869 side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node edge */
870 side_set_node_list[node_pos+2] =
871 connect[connect_offset+shell_table[side_num][2]-1];
872 }
873 }
874 break;
875 }
876 case EX_EL_TETRA:
877 {
878 if (side_num+1 < 1 || side_num+1 > 4) /* side number range check */
879 {
880 exerrval = EX_BADPARAM;
881 sprintf(errmsg,
882 "Error: Invalid tetra face number %d in file id %d",
883 side_num+1, exoid);
884 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
885 free(connect);
886 free(elem_blk_parms);
887 free(elem_blk_ids);
888 free(ss_elem_ndx);
889 free(ss_elem_node_ndx);
890 free(ss_parm_ndx);
891 free(side_set_side_list);
892 free(side_set_elem_list);
893 return(EX_FATAL);
894 }
895
896 side_set_node_list[node_pos] =
897 connect[connect_offset+tetra_table[side_num][0]-1];
898 side_set_node_list[node_pos+1] =
899 connect[connect_offset+tetra_table[side_num][1]-1];
900 side_set_node_list[node_pos+2] =
901 connect[connect_offset+tetra_table[side_num][2]-1];
902 side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */
903 if (num_nodes_per_elem == 8)
904 {
905 side_set_node_cnt_list[ss_elem_ndx[j]] = 4; /* 4 node object */
906 side_set_node_list[node_pos+3] =
907 connect[connect_offset+tetra_table[side_num][3]-1];
908 }
909 else if (num_nodes_per_elem > 8)
910 {
911 side_set_node_cnt_list[ss_elem_ndx[j]] = 6; /* 6 node object */
912 side_set_node_list[node_pos+3] =
913 connect[connect_offset+tetra_table[side_num][3]-1];
914 side_set_node_list[node_pos+4] =
915 connect[connect_offset+tetra_table[side_num][4]-1];
916 side_set_node_list[node_pos+5] =
917 connect[connect_offset+tetra_table[side_num][5]-1];
918 }
919 break;
920 }
921 case EX_EL_WEDGE:
922 {
923 if (side_num+1 < 1 || side_num+1 > 5) /* side number range check */
924 {
925 exerrval = EX_BADPARAM;
926 sprintf(errmsg,
927 "Error: Invalid wedge face number %d in file id %d",
928 side_num+1, exoid);
929 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
930 free(connect);
931 free(elem_blk_parms);
932 free(elem_blk_ids);
933 free(ss_elem_ndx);
934 free(ss_elem_node_ndx);
935 free(ss_parm_ndx);
936 free(side_set_side_list);
937 free(side_set_elem_list);
938 return(EX_FATAL);
939 }
940
941 side_set_node_list[node_pos++] =
942 connect[connect_offset+wedge_table[side_num][0]-1];
943 side_set_node_list[node_pos++] =
944 connect[connect_offset+wedge_table[side_num][1]-1];
945 side_set_node_list[node_pos++] =
946 connect[connect_offset+wedge_table[side_num][2]-1];
947
948 if (wedge_table[side_num][3] == 0) { /* degenerate side? */
949 side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node side */
950 }
951 else
952 {
953 side_set_node_list[node_pos++] =
954 connect[connect_offset+wedge_table[side_num][3]-1];
955 side_set_node_cnt_list[ss_elem_ndx[j]] = 4; /* 4 node side */
956 }
957
958
959 if (num_nodes_per_elem > 6)
960 {
961 side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node object */
962 side_set_node_list[node_pos++] =
963 connect[connect_offset+wedge_table[side_num][4]-1];
964 side_set_node_list[node_pos++] =
965 connect[connect_offset+wedge_table[side_num][5]-1];
966 side_set_node_list[node_pos++] =
967 connect[connect_offset+wedge_table[side_num][6]-1];
968
969 if (wedge_table[side_num][7] == 0) /* degenerate side? */
970 side_set_node_cnt_list[ss_elem_ndx[j]] = 6; /* 6 node side */
971 else
972 {
973 side_set_node_list[node_pos++] =
974 connect[connect_offset+wedge_table[side_num][7]-1];
975 side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node side */
976 }
977 }
978 break;
979 }
980 case EX_EL_PYRAMID:
981 {
982 if (side_num+1 < 1 || side_num+1 > 5) /* side number range check */
983 {
984 exerrval = EX_BADPARAM;
985 sprintf(errmsg,
986 "Error: Invalid pyramid face number %d in file id %d",
987 side_num+1, exoid);
988 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
989 free(connect);
990 free(elem_blk_parms);
991 free(elem_blk_ids);
992 free(ss_elem_ndx);
993 free(ss_elem_node_ndx);
994 free(ss_parm_ndx);
995 free(side_set_side_list);
996 free(side_set_elem_list);
997 return(EX_FATAL);
998 }
999
1000 side_set_node_list[node_pos++] =
1001 connect[connect_offset+pyramid_table[side_num][0]-1];
1002 side_set_node_list[node_pos++] =
1003 connect[connect_offset+pyramid_table[side_num][1]-1];
1004 side_set_node_list[node_pos++] =
1005 connect[connect_offset+pyramid_table[side_num][2]-1];
1006
1007 if (pyramid_table[side_num][3] == 0) { /* degenerate side? */
1008 side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node side */
1009 }
1010 else
1011 {
1012 side_set_node_list[node_pos++] =
1013 connect[connect_offset+pyramid_table[side_num][3]-1];
1014 side_set_node_cnt_list[ss_elem_ndx[j]] = 4; /* 4 node side */
1015 }
1016
1017
1018 if (num_nodes_per_elem > 5)
1019 {
1020 side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node object */
1021 side_set_node_list[node_pos++] =
1022 connect[connect_offset+pyramid_table[side_num][4]-1];
1023 side_set_node_list[node_pos++] =
1024 connect[connect_offset+pyramid_table[side_num][5]-1];
1025 side_set_node_list[node_pos++] =
1026 connect[connect_offset+pyramid_table[side_num][6]-1];
1027
1028 if (pyramid_table[side_num][7] == 0) /* degenerate side? */
1029 side_set_node_cnt_list[ss_elem_ndx[j]] = 6; /* 6 node side */
1030 else
1031 {
1032 side_set_node_list[node_pos++] =
1033 connect[connect_offset+pyramid_table[side_num][7]-1];
1034 side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node side */
1035 }
1036 }
1037 break;
1038 }
1039 case EX_EL_HEX:
1040 {
1041 if (side_num+1 < 1 || side_num+1 > 6) /* side number range check */
1042 {
1043 exerrval = EX_BADPARAM;
1044 sprintf(errmsg,
1045 "Error: Invalid hex face number %d in file id %d",
1046 side_num+1, exoid);
1047 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
1048 free(connect);
1049 free(elem_blk_parms);
1050 free(elem_blk_ids);
1051 free(ss_elem_ndx);
1052 free(ss_elem_node_ndx);
1053 free(ss_parm_ndx);
1054 free(side_set_side_list);
1055 free(side_set_elem_list);
1056 return(EX_FATAL);
1057 }
1058
1059 side_set_node_list[node_pos] =
1060 connect[connect_offset+hex_table[side_num][0]-1];
1061 side_set_node_list[node_pos+1] =
1062 connect[connect_offset+hex_table[side_num][1]-1];
1063 side_set_node_list[node_pos+2] =
1064 connect[connect_offset+hex_table[side_num][2]-1];
1065 side_set_node_list[node_pos+3] =
1066 connect[connect_offset+hex_table[side_num][3]-1];
1067 side_set_node_cnt_list[ss_elem_ndx[j]] = 4; /* 4 node object */
1068 if (num_nodes_per_elem > 12) /* more nodes than HEXSHELL */
1069 {
1070 side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node object */
1071 side_set_node_list[node_pos+4] =
1072 connect[connect_offset+hex_table[side_num][4]-1];
1073 side_set_node_list[node_pos+5] =
1074 connect[connect_offset+hex_table[side_num][5]-1];
1075 side_set_node_list[node_pos+6] =
1076 connect[connect_offset+hex_table[side_num][6]-1];
1077 side_set_node_list[node_pos+7] =
1078 connect[connect_offset+hex_table[side_num][7]-1];
1079 }
1080 if (num_nodes_per_elem == 27) /* 27-node brick */
1081 {
1082 side_set_node_cnt_list[ss_elem_ndx[j]] = 9; /* 9 node object */
1083 side_set_node_list[node_pos+8] =
1084 connect[connect_offset+hex_table[side_num][8]-1];
1085 }
1086 break;
1087 }
1088 default:
1089 {
1090 exerrval = EX_BADPARAM;
1091 sprintf(errmsg,
1092 "Error: %s is an unsupported element type",
1093 elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_type);
1094 ex_err("ex_get_side_set_node_list",errmsg,exerrval);
1095 return(EX_FATAL);
1096 }
1097 }
1098 }
1099
1100
1101 /* All done: release connectivity array space, element block ids array,
1102 element block parameters array, and side set element index array */
1103 free(connect);
1104 free(ss_parm_ndx);
1105 free(elem_blk_ids);
1106 free(elem_blk_parms);
1107 free(ss_elem_ndx);
1108 free(ss_elem_node_ndx);
1109 free(side_set_side_list);
1110 free(side_set_elem_list);
1111
1112 return(EX_NOERR);
1113 }
1114