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 * exgssc - ex_get_side_set_node_count
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 * revision history -
48 *
49 *****************************************************************************/
50 
51 #include <ctype.h>
52 #include <string.h>
53 #include <stdlib.h>
54 #include <assert.h>
55 #include "exodusII.h"
56 #include "exodusII_int.h"
57 
58 /* Generic error message for element type/node count mapping...*/
el_node_count_error(struct elem_blk_parm elem_blk_parms)59 static int el_node_count_error(struct elem_blk_parm elem_blk_parms)
60 {
61   char errmsg[MAX_ERR_LENGTH];
62   sprintf(errmsg,
63 	  "Error: An element of type '%s' with %d nodes is not valid.",
64 	  elem_blk_parms.elem_type,
65 	  elem_blk_parms.num_nodes_per_elem);
66   ex_err("ex_get_side_set_node_count",errmsg,EX_MSG);
67   return(EX_FATAL);
68 }
69 
ex_get_side_set_node_count(int exoid,ex_entity_id side_set_id,int * side_set_node_cnt_list)70 int ex_get_side_set_node_count(int exoid,
71                                ex_entity_id side_set_id,
72                                int *side_set_node_cnt_list)
73 {
74   size_t m;
75   int ii, i, j;
76   int  num_side_sets, num_elem_blks, num_df, ndim;
77   size_t tot_num_ss_elem = 0;
78   int64_t side, elem;
79   void_int *elem_blk_ids;
80   void_int *ss_elem_ndx;
81   void_int *side_set_elem_list, *side_set_side_list;
82   size_t elem_ctr;
83 
84   struct elem_blk_parm  *elem_blk_parms;
85 
86   char errmsg[MAX_ERR_LENGTH];
87 
88   exerrval = 0; /* clear error code */
89 
90   /* first check if any side sets are specified */
91   /* inquire how many side sets have been stored */
92   num_side_sets = ex_inquire_int(exoid, EX_INQ_SIDE_SETS);
93   if (num_side_sets < 0) {
94     sprintf(errmsg,
95 	    "Error: failed to get number of side sets in file id %d",exoid);
96     ex_err("ex_get_side_set_node_count",errmsg,exerrval);
97     return(EX_FATAL);
98   }
99 
100   if (num_side_sets == 0) {
101     sprintf(errmsg,
102 	    "Warning: no side sets defined in file id %d",exoid);
103     ex_err("ex_get_side_set_node_count",errmsg,EX_WARN);
104     return(EX_WARN);
105   }
106 
107   /* Lookup index of side set id in VAR_SS_IDS array */
108   ex_id_lkup(exoid,EX_SIDE_SET,side_set_id);
109   if (exerrval != 0)
110     {
111       if (exerrval == EX_NULLENTITY)
112 	{
113 	  sprintf(errmsg,
114 		  "Warning: side set %"PRId64" is NULL in file id %d",
115 		  side_set_id,exoid);
116 	  ex_err("ex_get_side_set_node_count",errmsg,EX_MSG);
117 	  return (EX_WARN);
118 	}
119       else
120 	{
121 
122 	  sprintf(errmsg,
123 		  "Error: failed to locate side set %"PRId64" in VAR_SS_IDS array in file id %d",
124 		  side_set_id,exoid);
125 	  ex_err("ex_get_side_set_node_count",errmsg,exerrval);
126 	  return (EX_FATAL);
127 	}
128     }
129 
130   num_elem_blks = ex_inquire_int(exoid, EX_INQ_ELEM_BLK);
131   if (num_elem_blks < 0) {
132     sprintf(errmsg,
133 	    "Error: failed to get number of element blocks in file id %d",exoid);
134     ex_err("ex_get_side_set_node_count",errmsg,exerrval);
135     return(EX_FATAL);
136   }
137 
138   /* get the dimensionality of the coordinates;  this is necessary to
139      distinguish between 2d TRIs and 3d TRIs */
140   ndim = ex_inquire_int(exoid, EX_INQ_DIM);
141   if (ndim < 0) {
142     sprintf(errmsg,
143 	    "Error: failed to get dimensionality in file id %d",exoid);
144     ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
145     return(EX_FATAL);
146   }
147 
148   /* First determine the  # of elements in the side set*/
149   if ((ex_get_side_set_param(exoid,side_set_id,&tot_num_ss_elem,&num_df)) == -1)
150     {
151       sprintf(errmsg,
152 	      "Error: failed to get number of elements in side set %"PRId64" in file id %d",
153 	      side_set_id, exoid);
154       ex_err("ex_get_side_set_node_count",errmsg,exerrval);
155       return(EX_FATAL);
156     }
157 
158   /* Allocate space for the side set element list */
159   {
160     int int_size = sizeof(int);
161     if (ex_int64_status(exoid) & EX_BULK_INT64_API)
162       int_size = sizeof(int64_t);
163 
164     if (!(side_set_elem_list=malloc(tot_num_ss_elem*int_size))) {
165       exerrval = EX_MEMFAIL;
166       sprintf(errmsg,
167 	      "Error: failed to allocate space for side set element list for file id %d",
168 	      exoid);
169       ex_err("ex_get_side_set_node_count",errmsg,exerrval);
170       return (EX_FATAL);
171     }
172 
173     /* Allocate space for the side set side list */
174     if (!(side_set_side_list=malloc(tot_num_ss_elem*int_size))) {
175       free(side_set_elem_list);
176       exerrval = EX_MEMFAIL;
177       sprintf(errmsg,
178 	      "Error: failed to allocate space for side set side list for file id %d",
179 	      exoid);
180       ex_err("ex_get_side_set_node_count",errmsg,exerrval);
181       return (EX_FATAL);
182     }
183 
184     if (ex_get_side_set(exoid, side_set_id,
185 			side_set_elem_list, side_set_side_list) == -1) {
186       free(side_set_elem_list);
187       free(side_set_side_list);
188       sprintf(errmsg,
189 	      "Error: failed to get side set %"PRId64" in file id %d",
190 	      side_set_id, exoid);
191       ex_err("ex_get_side_set_node_count",errmsg,exerrval);
192       return (EX_FATAL);
193     }
194 
195     /* Allocate space for the ss element index array */
196     if (!(ss_elem_ndx=malloc(tot_num_ss_elem*int_size))) {
197       free(side_set_elem_list);
198       free(side_set_side_list);
199       exerrval = EX_MEMFAIL;
200       sprintf(errmsg,
201 	      "Error: failed to allocate space for side set elem sort array for file id %d",
202 	      exoid);
203       ex_err("ex_get_side_set_node_count",errmsg,exerrval);
204       return (EX_FATAL);
205     }
206 
207     if (int_size == sizeof(int64_t)) {
208       /* Sort side set element list into index array  - non-destructive */
209       int64_t *elems = (int64_t*)ss_elem_ndx;
210       for (i=0;i<tot_num_ss_elem;i++) {
211 	elems[i] = i; /* init index array to current position */
212       }
213       ex_iqsort64(side_set_elem_list, elems,tot_num_ss_elem);
214     } else {
215       /* Sort side set element list into index array  - non-destructive */
216       int *elems = (int*)ss_elem_ndx;
217       for (i=0;i<tot_num_ss_elem;i++) {
218 	elems[i] = i; /* init index array to current position */
219       }
220       ex_iqsort(side_set_elem_list, elems,tot_num_ss_elem);
221     }
222   }
223 
224   /* Allocate space for the element block ids */
225   {
226     int int_size = sizeof(int);
227     if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
228       int_size = sizeof(int64_t);
229     }
230 
231     if (!(elem_blk_ids=malloc(num_elem_blks*int_size))) {
232       exerrval = EX_MEMFAIL;
233       free(ss_elem_ndx);
234       free(side_set_side_list);
235       free(side_set_elem_list);
236       sprintf(errmsg,
237 	      "Error: failed to allocate space for element block ids for file id %d",
238 	      exoid);
239       ex_err("ex_get_side_set_node_count",errmsg,exerrval);
240       return (EX_FATAL);
241     }
242 
243     if (ex_get_elem_blk_ids(exoid, elem_blk_ids) == -1) {
244       free(elem_blk_ids);
245       free(ss_elem_ndx);
246       free(side_set_side_list);
247       free(side_set_elem_list);
248       sprintf(errmsg,
249 	      "Error: failed to get element block ids in file id %d",
250 	      exoid);
251       ex_err("ex_get_side_set_node_count",errmsg,EX_MSG);
252       return(EX_FATAL);
253     }
254   }
255 
256   /* Allocate space for the element block params */
257   if (!(elem_blk_parms=malloc(num_elem_blks*sizeof(struct elem_blk_parm)))) {
258     free(elem_blk_ids);
259     free(ss_elem_ndx);
260     free(side_set_side_list);
261     free(side_set_elem_list);
262     exerrval = EX_MEMFAIL;
263     sprintf(errmsg,
264 	    "Error: failed to allocate space for element block params for file id %d",
265             exoid);
266     ex_err("ex_get_side_set_node_count",errmsg,exerrval);
267     return (EX_FATAL);
268   }
269 
270   elem_ctr = 0;
271   for (i=0; i<num_elem_blks; i++) {
272     ex_entity_id id;
273     ex_block block;
274     if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
275       id = ((int64_t*)elem_blk_ids)[i];
276     } else {
277       id = ((int*)elem_blk_ids)[i];
278     }
279 
280     /* read in an element block parameter */
281     block.type = EX_ELEM_BLOCK;
282     block.id = id;
283     if ((ex_get_block_param (exoid, &block)) == -1) {
284       free(elem_blk_parms);
285       free(elem_blk_ids);
286       free(ss_elem_ndx);
287       free(side_set_side_list);
288       free(side_set_elem_list);
289       sprintf(errmsg,
290 	      "Error: failed to get element block %"PRId64" parameters in file id %d",
291               block.id, exoid);
292       ex_err("ex_get_side_set_node_count",errmsg,EX_MSG);
293       return(EX_FATAL);
294     }
295 
296     elem_blk_parms[i].num_elem_in_blk = block.num_entry;
297     elem_blk_parms[i].num_nodes_per_elem = block.num_nodes_per_entry;
298     elem_blk_parms[i].num_attr = block.num_attribute;
299 
300     for (m=0; m < strlen(block.topology); m++) {
301       elem_blk_parms[i].elem_type[m] = toupper(block.topology[m]);
302     }
303     elem_blk_parms[i].elem_type[m] = '\0';
304 
305     if (strncmp(elem_blk_parms[i].elem_type,"CIRCLE",3) == 0)
306       {
307 	elem_blk_parms[i].elem_type_val = EX_EL_CIRCLE;
308 	elem_blk_parms[i].num_sides = 1;
309 	elem_blk_parms[i].num_nodes_per_side[0] = 1;
310       }
311     else if (strncmp(elem_blk_parms[i].elem_type,"SPHERE",3) == 0)
312       {
313 	elem_blk_parms[i].elem_type_val = EX_EL_SPHERE;
314 	elem_blk_parms[i].num_sides = 1;
315         elem_blk_parms[i].num_nodes_per_side[0] = 1;
316       }
317     else if (strncmp(elem_blk_parms[i].elem_type,"QUAD",3) == 0)
318       {
319 	elem_blk_parms[i].elem_type_val = EX_EL_QUAD;
320 	elem_blk_parms[i].num_sides = 4;
321 	if (elem_blk_parms[i].num_nodes_per_elem == 4) {
322 	  elem_blk_parms[i].num_nodes_per_side[0] = 2;
323 	  elem_blk_parms[i].num_nodes_per_side[1] = 2;
324 	  elem_blk_parms[i].num_nodes_per_side[2] = 2;
325 	  elem_blk_parms[i].num_nodes_per_side[3] = 2;
326 	} else if (elem_blk_parms[i].num_nodes_per_elem == 5) {
327 	  elem_blk_parms[i].num_nodes_per_side[0] = 2;
328 	  elem_blk_parms[i].num_nodes_per_side[1] = 2;
329 	  elem_blk_parms[i].num_nodes_per_side[2] = 2;
330 	  elem_blk_parms[i].num_nodes_per_side[3] = 2;
331 	} else if (elem_blk_parms[i].num_nodes_per_elem == 9 ||
332 		   elem_blk_parms[i].num_nodes_per_elem == 8) {
333 	  elem_blk_parms[i].num_nodes_per_side[0] = 3;
334 	  elem_blk_parms[i].num_nodes_per_side[1] = 3;
335 	  elem_blk_parms[i].num_nodes_per_side[2] = 3;
336 	  elem_blk_parms[i].num_nodes_per_side[3] = 3;
337 	} else {
338 	  return el_node_count_error(elem_blk_parms[i]);
339 	}
340       }
341     else if (strncmp(elem_blk_parms[i].elem_type,"TRIANGLE",3) == 0)
342       {
343 	elem_blk_parms[i].elem_type_val = EX_EL_TRIANGLE;
344 	if (ndim == 2) { /* 2d TRIs */
345 	  elem_blk_parms[i].num_sides = 3;
346 	  if (elem_blk_parms[i].num_nodes_per_elem == 3) {
347 	    elem_blk_parms[i].num_nodes_per_side[0] = 2;
348 	    elem_blk_parms[i].num_nodes_per_side[1] = 2;
349 	    elem_blk_parms[i].num_nodes_per_side[2] = 2;
350 	  } else if (elem_blk_parms[i].num_nodes_per_elem == 6) {
351 	    elem_blk_parms[i].num_nodes_per_side[0] = 3;
352 	    elem_blk_parms[i].num_nodes_per_side[1] = 3;
353 	    elem_blk_parms[i].num_nodes_per_side[2] = 3;
354 	  }
355 	} else if (ndim == 3) { /* 3d TRIs -- triangular shell*/
356 	  elem_blk_parms[i].num_sides = 5; /* 2 Faces and 3 Edges */
357 	  if (elem_blk_parms[i].num_nodes_per_elem == 3) {
358 	    elem_blk_parms[i].num_nodes_per_side[0] = 3;
359 	    elem_blk_parms[i].num_nodes_per_side[1] = 3;
360 	    elem_blk_parms[i].num_nodes_per_side[2] = 2;
361 	    elem_blk_parms[i].num_nodes_per_side[3] = 2;
362 	    elem_blk_parms[i].num_nodes_per_side[4] = 2;
363 	  } else if (elem_blk_parms[i].num_nodes_per_elem == 6) {
364 	    elem_blk_parms[i].num_nodes_per_side[0] = 6;
365 	    elem_blk_parms[i].num_nodes_per_side[1] = 6;
366 	    elem_blk_parms[i].num_nodes_per_side[2] = 3;
367 	    elem_blk_parms[i].num_nodes_per_side[3] = 3;
368 	    elem_blk_parms[i].num_nodes_per_side[4] = 3;
369 	  } else {
370 	    return el_node_count_error(elem_blk_parms[i]);
371 	  }
372 	}
373       }
374     else if (strncmp(elem_blk_parms[i].elem_type,"SHELL",3) == 0)
375       {
376 	elem_blk_parms[i].elem_type_val = EX_EL_SHELL;
377 
378 	if (elem_blk_parms[i].num_nodes_per_elem == 2) {/* KLUDGE for 2D Shells*/
379 	  elem_blk_parms[i].num_sides = 2;
380 	  elem_blk_parms[i].num_nodes_per_side[0] = 2;
381 	  elem_blk_parms[i].num_nodes_per_side[1] = 2;
382 	} else if (elem_blk_parms[i].num_nodes_per_elem == 4) {
383 	  elem_blk_parms[i].num_sides = 6;  /* 2 Faces, 4 Edges */
384 	  elem_blk_parms[i].num_nodes_per_side[0] = 4;
385 	  elem_blk_parms[i].num_nodes_per_side[1] = 4;
386 	  elem_blk_parms[i].num_nodes_per_side[2] = 2;
387 	  elem_blk_parms[i].num_nodes_per_side[3] = 2;
388 	  elem_blk_parms[i].num_nodes_per_side[4] = 2;
389 	  elem_blk_parms[i].num_nodes_per_side[5] = 2;
390 	} else if (elem_blk_parms[i].num_nodes_per_elem == 8 ||
391 		   elem_blk_parms[i].num_nodes_per_elem == 9) {
392 	  elem_blk_parms[i].num_sides = 6;  /* 2 Faces, 4 Edges */
393 	  elem_blk_parms[i].num_nodes_per_side[0] =
394 	    elem_blk_parms[i].num_nodes_per_elem; /* 8 or 9 */
395 	  elem_blk_parms[i].num_nodes_per_side[1] =
396 	    elem_blk_parms[i].num_nodes_per_elem; /* 8 or 9 */
397 	  elem_blk_parms[i].num_nodes_per_side[2] = 3;
398 	  elem_blk_parms[i].num_nodes_per_side[3] = 3;
399 	  elem_blk_parms[i].num_nodes_per_side[4] = 3;
400 	  elem_blk_parms[i].num_nodes_per_side[5] = 3;
401 	} else {
402 	  return el_node_count_error(elem_blk_parms[i]);
403 	}
404       }
405     else if (strncmp(elem_blk_parms[i].elem_type,"HEX",3) == 0)
406       {
407 	elem_blk_parms[i].elem_type_val = EX_EL_HEX;
408 	elem_blk_parms[i].num_sides = 6;
409 	/* determine side set node stride */
410 	if (elem_blk_parms[i].num_nodes_per_elem == 8) {  /* 8-node bricks */
411 	  elem_blk_parms[i].num_nodes_per_side[0] = 4;
412 	  elem_blk_parms[i].num_nodes_per_side[1] = 4;
413 	  elem_blk_parms[i].num_nodes_per_side[2] = 4;
414 	  elem_blk_parms[i].num_nodes_per_side[3] = 4;
415 	  elem_blk_parms[i].num_nodes_per_side[4] = 4;
416 	  elem_blk_parms[i].num_nodes_per_side[5] = 4;
417 	} else if (elem_blk_parms[i].num_nodes_per_elem == 9) { /* 9-node bricks */
418 	  elem_blk_parms[i].num_nodes_per_side[0] = 4;
419 	  elem_blk_parms[i].num_nodes_per_side[1] = 4;
420 	  elem_blk_parms[i].num_nodes_per_side[2] = 4;
421 	  elem_blk_parms[i].num_nodes_per_side[3] = 4;
422 	  elem_blk_parms[i].num_nodes_per_side[4] = 4;
423 	  elem_blk_parms[i].num_nodes_per_side[5] = 4;
424 	} else if (elem_blk_parms[i].num_nodes_per_elem == 12) { /* HEXSHELLS */
425 	  elem_blk_parms[i].num_nodes_per_side[0] = 6;
426 	  elem_blk_parms[i].num_nodes_per_side[1] = 6;
427 	  elem_blk_parms[i].num_nodes_per_side[2] = 6;
428 	  elem_blk_parms[i].num_nodes_per_side[3] = 6;
429 	  elem_blk_parms[i].num_nodes_per_side[4] = 4;
430 	  elem_blk_parms[i].num_nodes_per_side[5] = 4;
431 	} else if (elem_blk_parms[i].num_nodes_per_elem == 20) { /* 20-node bricks */
432 	  elem_blk_parms[i].num_nodes_per_side[0] = 8;
433 	  elem_blk_parms[i].num_nodes_per_side[1] = 8;
434 	  elem_blk_parms[i].num_nodes_per_side[2] = 8;
435 	  elem_blk_parms[i].num_nodes_per_side[3] = 8;
436 	  elem_blk_parms[i].num_nodes_per_side[4] = 8;
437 	  elem_blk_parms[i].num_nodes_per_side[5] = 8;
438 	} else if (elem_blk_parms[i].num_nodes_per_elem == 27) { /* 27-node bricks */
439 	  elem_blk_parms[i].num_nodes_per_side[0] = 9;
440 	  elem_blk_parms[i].num_nodes_per_side[1] = 9;
441 	  elem_blk_parms[i].num_nodes_per_side[2] = 9;
442 	  elem_blk_parms[i].num_nodes_per_side[3] = 9;
443 	  elem_blk_parms[i].num_nodes_per_side[4] = 9;
444 	  elem_blk_parms[i].num_nodes_per_side[5] = 9;
445 	} else {
446 	  return el_node_count_error(elem_blk_parms[i]);
447 	}
448       }
449     else if (strncmp(elem_blk_parms[i].elem_type,"TETRA",3) == 0)
450       {
451 	elem_blk_parms[i].elem_type_val = EX_EL_TETRA;
452 	elem_blk_parms[i].num_sides = 4;
453 	/* determine side set node stride */
454 	if (elem_blk_parms[i].num_nodes_per_elem == 4) {
455 	  elem_blk_parms[i].num_nodes_per_side[0] = 3;
456 	  elem_blk_parms[i].num_nodes_per_side[1] = 3;
457 	  elem_blk_parms[i].num_nodes_per_side[2] = 3;
458 	  elem_blk_parms[i].num_nodes_per_side[3] = 3;
459 	} else if (elem_blk_parms[i].num_nodes_per_elem == 8) {
460 	  elem_blk_parms[i].num_nodes_per_side[0] = 4;
461 	  elem_blk_parms[i].num_nodes_per_side[1] = 4;
462 	  elem_blk_parms[i].num_nodes_per_side[2] = 4;
463 	  elem_blk_parms[i].num_nodes_per_side[3] = 4;
464 	} else if (elem_blk_parms[i].num_nodes_per_elem == 10) {
465 	  elem_blk_parms[i].num_nodes_per_side[0] = 6;
466 	  elem_blk_parms[i].num_nodes_per_side[1] = 6;
467 	  elem_blk_parms[i].num_nodes_per_side[2] = 6;
468 	  elem_blk_parms[i].num_nodes_per_side[3] = 6;
469 	} else {
470 	  return el_node_count_error(elem_blk_parms[i]);
471 	}
472       }
473     else if (strncmp(elem_blk_parms[i].elem_type,"WEDGE",3) == 0)
474       {
475 	elem_blk_parms[i].elem_type_val = EX_EL_WEDGE;
476 	elem_blk_parms[i].num_sides = 5;
477 	if (elem_blk_parms[i].num_nodes_per_elem == 6) {
478 	  elem_blk_parms[i].num_nodes_per_side[0] = 4;
479 	  elem_blk_parms[i].num_nodes_per_side[1] = 4;
480 	  elem_blk_parms[i].num_nodes_per_side[2] = 4;
481 	  elem_blk_parms[i].num_nodes_per_side[3] = 3;
482 	  elem_blk_parms[i].num_nodes_per_side[4] = 3;
483 	} else if (elem_blk_parms[i].num_nodes_per_elem == 15){
484 	  elem_blk_parms[i].num_nodes_per_side[0] = 8;
485 	  elem_blk_parms[i].num_nodes_per_side[1] = 8;
486 	  elem_blk_parms[i].num_nodes_per_side[2] = 8;
487 	  elem_blk_parms[i].num_nodes_per_side[3] = 6;
488 	  elem_blk_parms[i].num_nodes_per_side[4] = 6;
489 	} else {
490 	  return el_node_count_error(elem_blk_parms[i]);
491 	}
492       }
493     else if (strncmp(elem_blk_parms[i].elem_type,"PYRAMID",3) == 0)
494       {
495 	elem_blk_parms[i].elem_type_val = EX_EL_PYRAMID;
496 	elem_blk_parms[i].num_sides = 5;
497 	if (elem_blk_parms[i].num_nodes_per_elem == 5) {
498 	  elem_blk_parms[i].num_nodes_per_side[0] = 3;
499 	  elem_blk_parms[i].num_nodes_per_side[1] = 3;
500 	  elem_blk_parms[i].num_nodes_per_side[2] = 3;
501 	  elem_blk_parms[i].num_nodes_per_side[3] = 3;
502 	  elem_blk_parms[i].num_nodes_per_side[4] = 4;
503 	} else if (elem_blk_parms[i].num_nodes_per_elem == 13){
504 	  elem_blk_parms[i].num_nodes_per_side[0] = 6;
505 	  elem_blk_parms[i].num_nodes_per_side[1] = 6;
506 	  elem_blk_parms[i].num_nodes_per_side[2] = 6;
507 	  elem_blk_parms[i].num_nodes_per_side[3] = 6;
508 	  elem_blk_parms[i].num_nodes_per_side[4] = 8;
509 	} else {
510 	  return el_node_count_error(elem_blk_parms[i]);
511 	}
512       }
513     else if (strncmp(elem_blk_parms[i].elem_type,"BEAM",3) == 0)
514       {
515 	elem_blk_parms[i].elem_type_val = EX_EL_BEAM;
516 	elem_blk_parms[i].num_sides = 2;
517 
518 	if (elem_blk_parms[i].num_nodes_per_elem == 2) {
519 	  elem_blk_parms[i].num_nodes_per_side[0] = 2;
520 	  elem_blk_parms[i].num_nodes_per_side[1] = 2;
521 	} else if (elem_blk_parms[i].num_nodes_per_elem == 3){
522 	  elem_blk_parms[i].num_nodes_per_side[0] = 3;
523 	  elem_blk_parms[i].num_nodes_per_side[1] = 3;
524 	} else {
525 	  return el_node_count_error(elem_blk_parms[i]);
526 	}
527       }
528     else if ( (strncmp(elem_blk_parms[i].elem_type,"TRUSS",3) == 0) ||
529               (strncmp(elem_blk_parms[i].elem_type,"BAR",3) == 0) ||
530               (strncmp(elem_blk_parms[i].elem_type,"EDGE",3) == 0) )
531       {
532 	elem_blk_parms[i].elem_type_val = EX_EL_TRUSS;
533 	elem_blk_parms[i].num_sides = 2;
534 
535 	if (elem_blk_parms[i].num_nodes_per_elem == 2) {
536 	  elem_blk_parms[i].num_nodes_per_side[0] = 2;
537 	  elem_blk_parms[i].num_nodes_per_side[1] = 2;
538 	} else if (elem_blk_parms[i].num_nodes_per_elem == 3) {
539 	  elem_blk_parms[i].num_nodes_per_side[0] = 3;
540 	  elem_blk_parms[i].num_nodes_per_side[1] = 3;
541 	} else {
542 	  return el_node_count_error(elem_blk_parms[i]);
543 	}
544       }
545     /* Used for an empty block in a parallel decomposition */
546     else if (strncmp(elem_blk_parms[i].elem_type,"NULL",3) == 0) {
547       elem_blk_parms[i].elem_type_val = EX_EL_NULL_ELEMENT;
548       elem_blk_parms[i].num_sides = 0;
549       elem_blk_parms[i].num_nodes_per_side[0] = 0;
550       elem_blk_parms[i].num_elem_in_blk = 0;
551     } else {
552       /* unsupported element type; no problem if no sides specified for
553          this element block */
554       elem_blk_parms[i].elem_type_val = EX_EL_UNK;
555       elem_blk_parms[i].num_sides = 0;
556       elem_blk_parms[i].num_nodes_per_side[0] = 0;
557     }
558 
559     elem_blk_parms[i].elem_blk_id = id;    /* save id */
560     elem_ctr += elem_blk_parms[i].num_elem_in_blk;
561     elem_blk_parms[i].elem_ctr = elem_ctr;      /* save elem number max */
562   }
563 
564 
565   /* Finally... Create the list of node counts for each face in the
566    * side set.
567    */
568 
569   j = 0; /* The current element block... */
570   for (ii=0;ii<tot_num_ss_elem;ii++) {
571 
572     if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
573       i    = ((int64_t*)ss_elem_ndx)[ii];
574       elem = ((int64_t*)side_set_elem_list)[i];
575       side = ((int64_t*)side_set_side_list)[i]-1; /* Convert to 0-based sides */
576     } else {
577       i    = ((int*)ss_elem_ndx)[ii];
578       elem = ((int*)side_set_elem_list)[i];
579       side = ((int*)side_set_side_list)[i]-1; /* Convert to 0-based sides */
580     }
581 
582     /*
583      * Since the elements are being accessed in sorted, order, the
584      * block that contains the elements must progress sequentially
585      * from block 0 to block[num_elem_blks-1]. Once we find an element
586      * not in this block, find a following block that contains it...
587      */
588     for ( ; j<num_elem_blks; j++) {
589       if (elem <= elem_blk_parms[j].elem_ctr) {
590         break;
591       }
592     }
593 
594     if (j < num_elem_blks) {
595       assert(side < elem_blk_parms[j].num_sides);
596       side_set_node_cnt_list[i] = elem_blk_parms[j].num_nodes_per_side[side];
597     } else {
598       exerrval = EX_BADPARAM;
599       sprintf(errmsg,
600 	      "Error: Invalid element number %"PRId64" found in side set %"PRId64" in file %d",
601               elem, side_set_id, exoid);
602       free(elem_blk_parms);
603       free(elem_blk_ids);
604       free(ss_elem_ndx);
605       free(side_set_side_list);
606       free(side_set_elem_list);
607       ex_err("ex_get_side_set_node_count",errmsg,EX_MSG);
608       return (EX_FATAL);
609     }
610   }
611 
612   /* All done: release connectivity array space, element block ids
613    * array, element block parameters array, and side set element index
614    * array
615    */
616   free(elem_blk_ids);
617   free(elem_blk_parms);
618   free(ss_elem_ndx);
619   free(side_set_side_list);
620   free(side_set_elem_list);
621 
622   return(EX_NOERR);
623 }
624