int ex_cvt_nodes_to_sides(int exoid, void_int *num_elem_per_set, void_int *num_nodes_per_set, void_int *side_sets_elem_index, /* unused */ void_int *side_sets_node_index, /* unused */ void_int *side_sets_elem_list, void_int *side_sets_node_list, void_int *side_sets_side_list) { size_t i, j, k, n; int num_side_sets, num_elem_blks; int64_t tot_num_elem = 0, tot_num_ss_elem = 0, elem_num = 0, ndim; void_int *elem_blk_ids = NULL; void_int *connect = NULL; void_int *ss_elem_ndx = NULL; void_int *ss_elem_node_ndx = NULL; void_int *ss_parm_ndx = NULL; size_t elem_ctr, node_ctr, elem_num_pos; int num_nodes_per_elem, num_node_per_side; int *same_elem_type = NULL; int el_type = 0; int int_size; int ids_size; struct elem_blk_parm *elem_blk_parms = NULL; int err_stat = EX_NOERR; /* node to side translation tables - These tables are used to look up the side number based on the first and second node in the side/face list. The side node order is found in the original Exodus document, SAND87-2997. The element node order is found in the ExodusII document, SAND92-2137. These tables were generated by following the right-hand rule for determining the outward normal. Note: Only the more complex 3-D shapes require these tables, the simple shapes are trivial - the first node found is also the side number. */ /* 1 2 3 4 node 1 */ static int shell_table[2][8] = { {2, 4, 3, 1, 4, 2, 1, 3}, /* node 2 */ {1, 2, 1, 2, 1, 2, 1, 2} /* side # */ }; /* 1 2 3 4 node 1 */ static int shell_edge_table[2][8] = { {2, 4, 3, 1, 4, 2, 1, 3}, /* node 2 */ {3, 6, 4, 3, 5, 4, 6, 5} /* side # */ }; /* 1 2 3 node 1 */ static int trishell_table[2][6] = { {2, 3, 3, 1, 1, 2}, /* node 2 */ {1, 2, 1, 2, 1, 2} /* side # */ }; /* 1 2 3 4 node 1 */ static int tetra_table[2][12] = { {2, 3, 4, 1, 3, 4, 4, 1, 2, 1, 2, 3}, /* node 2 */ {1, 4, 3, 4, 2, 1, 2, 3, 4, 1, 2, 3} /* side # */ }; #if 0 static int wedge_table[2][18] = { /* 1 2 3 4 5 6 node 1 */ {2,4,3, 5,1,3, 6,1,2, 1,6,5, 6,2,4, 4,3,5}, /* node 2 */ {1,3,4, 1,4,2, 2,3,4, 1,3,5, 5,2,1, 5,3,2} /* side # */ }; #endif static int hex_table[2][24] = { /* 1 2 3 4 5 6 7 8 node 1 */ {4, 2, 5, 1, 3, 6, 7, 4, 2, 3, 1, 8, 6, 8, 1, 5, 2, 7, 8, 6, 3, 7, 5, 4}, /* node 2 */ {5, 1, 4, 5, 2, 1, 2, 3, 5, 5, 4, 3, 6, 4, 1, 1, 2, 6, 6, 2, 3, 3, 6, 4} /* side # */ }; char errmsg[MAX_ERR_LENGTH]; ex_check_valid_file_id(exoid); exerrval = 0; /* clear error code */ /* first check if any side sets are specified */ /* inquire how many side sets have been stored */ num_side_sets = ex_inquire_int(exoid, EX_INQ_SIDE_SETS); if (num_side_sets < 0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get number of side sets in file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); return (EX_FATAL); } if (num_side_sets == 0) { snprintf(errmsg, MAX_ERR_LENGTH, "Warning: no side sets defined in file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, EX_WARN); return (EX_WARN); } num_elem_blks = ex_inquire_int(exoid, EX_INQ_ELEM_BLK); if (num_elem_blks < 0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get number of element blocks in file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); return (EX_FATAL); } tot_num_elem = ex_inquire_int(exoid, EX_INQ_ELEM); if (tot_num_elem < 0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get total number of elements in file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); return (EX_FATAL); } /* get the dimensionality of the coordinates; this is necessary to distinguish between 2d TRIs and 3d TRIs */ ndim = ex_inquire_int(exoid, EX_INQ_DIM); int_size = sizeof(int); if (ex_int64_status(exoid) & EX_BULK_INT64_API) { int_size = sizeof(int64_t); } /* First count up # of elements in the side sets*/ if (ex_int64_status(exoid) & EX_BULK_INT64_API) { for (i = 0; i < num_side_sets; i++) { tot_num_ss_elem += ((int64_t *)num_elem_per_set)[i]; } } else { for (i = 0; i < num_side_sets; i++) { tot_num_ss_elem += ((int *)num_elem_per_set)[i]; } } /* Allocate space for the ss element index array */ if (!(ss_elem_ndx = malloc(tot_num_ss_elem * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set elem sort " "array for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } if (int_size == sizeof(int64_t)) { /* Sort side set element list into index array - non-destructive */ int64_t *elems = (int64_t *)ss_elem_ndx; for (i = 0; i < tot_num_ss_elem; i++) { elems[i] = i; /* init index array to current position */ } ex_iqsort64(side_sets_elem_list, elems, tot_num_ss_elem); } else { /* Sort side set element list into index array - non-destructive */ int *elems = (int *)ss_elem_ndx; for (i = 0; i < tot_num_ss_elem; i++) { elems[i] = i; /* init index array to current position */ } ex_iqsort(side_sets_elem_list, elems, tot_num_ss_elem); } /* Allocate space for the element block ids */ ids_size = sizeof(int); if (ex_int64_status(exoid) & EX_IDS_INT64_API) { ids_size = sizeof(int64_t); } if (!(elem_blk_ids = malloc(num_elem_blks * ids_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for element block ids for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } if (ex_get_ids(exoid, EX_ELEM_BLOCK, elem_blk_ids)) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get element block ids in file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, EX_MSG); err_stat = EX_FATAL; goto cleanup; } /* Allocate space for the element block params */ if (!(elem_blk_parms = malloc(num_elem_blks * sizeof(struct elem_blk_parm)))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for element block params " "for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } elem_ctr = 0; for (i = 0; i < num_elem_blks; i++) { ex_entity_id id; if (ex_int64_status(exoid) & EX_IDS_INT64_API) { id = ((int64_t *)elem_blk_ids)[i]; } else { id = ((int *)elem_blk_ids)[i]; } err_stat = ex_int_get_block_param(exoid, id, ndim, &elem_blk_parms[i]); if (err_stat != EX_NOERR) { goto cleanup; } elem_ctr += elem_blk_parms[i].num_elem_in_blk; elem_blk_parms[i].elem_ctr = elem_ctr; /* save elem number max */ } /* Allocate space for the ss element to element block parameter index array */ if (!(ss_parm_ndx = malloc(tot_num_ss_elem * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set elem parms " "index for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } /* Allocate space for the ss element to node list index array */ if (!(ss_elem_node_ndx = malloc((tot_num_ss_elem + 1) * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set elem to node " "index for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } /* determine if each side set has uniform element types; this will be used to help determine the stride through the node list */ /* Allocate space for same element type flag array*/ if (!(same_elem_type = malloc(num_side_sets * sizeof(int)))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for element type flag " "array for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } same_elem_type[0] = EX_TRUE; if (ex_int64_status(exoid) & EX_BULK_INT64_API) { elem_ctr = ((int64_t *)num_elem_per_set)[0]; for (i = 0, k = 0; i < tot_num_ss_elem; i++) { int64_t elem = ((int64_t *)side_sets_elem_list)[i]; for (j = 0; j < num_elem_blks; j++) { if (elem <= elem_blk_parms[j].elem_ctr) { break; } } if (j >= num_elem_blks) { exerrval = EX_INTERNAL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: internal logic error for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } if (i == 0) { el_type = elem_blk_parms[j].elem_type_val; } /* determine which side set this element is in; assign to kth side set */ if (i >= elem_ctr) { elem_ctr += ((int64_t *)num_elem_per_set)[++k]; el_type = elem_blk_parms[j].elem_type_val; same_elem_type[k] = EX_TRUE; } if (el_type != elem_blk_parms[j].elem_type_val) { same_elem_type[k] = EX_FALSE; } } /* Build side set element to node list index and side set element parameter index. */ node_ctr = 0; elem_ctr = ((int64_t *)num_elem_per_set)[0]; for (i = 0, k = 0; i < tot_num_ss_elem; i++) { int64_t elem = ((int64_t *)side_sets_elem_list)[i]; for (j = 0; j < num_elem_blks; j++) { if (elem <= elem_blk_parms[j].elem_ctr) { break; } } if (j >= num_elem_blks) { exerrval = EX_INTERNAL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: internal logic error for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } ((int64_t *)ss_parm_ndx)[i] = j; /* assign parameter block index */ ((int64_t *)ss_elem_node_ndx)[i] = node_ctr; /* assign node list index */ /* determine which side set this element is in; assign to kth side set */ if (i >= elem_ctr) { /* skip over NULL side sets */ while (((int64_t *)num_elem_per_set)[++k] == 0) { ; } elem_ctr += ((int64_t *)num_elem_per_set)[k]; } /* determine number of nodes per side */ if (((((int64_t *)num_nodes_per_set)[k] % ((int64_t *)num_elem_per_set)[k]) == 0) && (same_elem_type[k] == EX_TRUE)) { /* all side set elements are same type */ node_ctr += ((int64_t *)num_nodes_per_set)[k] / ((int64_t *)num_elem_per_set)[k]; } else { node_ctr += elem_blk_parms[j].num_nodes_per_side[0]; } } ((int64_t *)ss_elem_node_ndx)[i] = node_ctr; /* assign node list index */ } else { elem_ctr = ((int *)num_elem_per_set)[0]; for (i = 0, k = 0; i < tot_num_ss_elem; i++) { int elem = ((int *)side_sets_elem_list)[i]; for (j = 0; j < num_elem_blks; j++) { if (elem <= elem_blk_parms[j].elem_ctr) { break; } } if (j >= num_elem_blks) { exerrval = EX_INTERNAL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: internal logic error for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } if (i == 0) { el_type = elem_blk_parms[j].elem_type_val; } /* determine which side set this element is in; assign to kth side set */ if (i >= elem_ctr) { elem_ctr += ((int *)num_elem_per_set)[++k]; el_type = elem_blk_parms[j].elem_type_val; same_elem_type[k] = EX_TRUE; } if (el_type != elem_blk_parms[j].elem_type_val) { same_elem_type[k] = EX_FALSE; } } /* Build side set element to node list index and side set element parameter index. */ node_ctr = 0; elem_ctr = ((int *)num_elem_per_set)[0]; for (i = 0, k = 0; i < tot_num_ss_elem; i++) { int elem = ((int *)side_sets_elem_list)[i]; for (j = 0; j < num_elem_blks; j++) { if (elem <= elem_blk_parms[j].elem_ctr) { break; } } if (j >= num_elem_blks) { exerrval = EX_INTERNAL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: internal logic error for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } ((int *)ss_parm_ndx)[i] = j; /* assign parameter block index */ ((int *)ss_elem_node_ndx)[i] = node_ctr; /* assign node list index */ /* determine which side set this element is in; assign to kth side set */ if (i >= elem_ctr) { /* skip over NULL side sets */ while (((int *)num_elem_per_set)[++k] == 0) { ; } elem_ctr += ((int *)num_elem_per_set)[k]; } /* determine number of nodes per side */ if (((((int *)num_nodes_per_set)[k] % ((int *)num_elem_per_set)[k]) == 0) && (same_elem_type[k])) { /* all side set elements are same type */ node_ctr += ((int *)num_nodes_per_set)[k] / ((int *)num_elem_per_set)[k]; } else { node_ctr += elem_blk_parms[j].num_nodes_per_side[0]; } } ((int *)ss_elem_node_ndx)[i] = node_ctr; /* assign node list index */ } /* All setup, ready to go ... */ elem_ctr = 0; for (j = 0; j < tot_num_ss_elem; j++) { int64_t elem; int64_t idx; int64_t ss_node0, ss_node1; int64_t p_ndx; if (int_size == sizeof(int64_t)) { idx = ((int64_t *)ss_elem_ndx)[j]; elem = ((int64_t *)side_sets_elem_list)[idx]; ss_node0 = ((int64_t *)side_sets_node_list)[((int64_t *)ss_elem_node_ndx)[idx]]; ss_node1 = ((int64_t *)side_sets_node_list)[((int64_t *)ss_elem_node_ndx)[idx] + 1]; p_ndx = ((int64_t *)ss_parm_ndx)[idx]; } else { idx = ((int *)ss_elem_ndx)[j]; elem = ((int *)side_sets_elem_list)[idx]; ss_node0 = ((int *)side_sets_node_list)[((int *)ss_elem_node_ndx)[idx]]; ss_node1 = ((int *)side_sets_node_list)[((int *)ss_elem_node_ndx)[idx] + 1]; p_ndx = ((int *)ss_parm_ndx)[idx]; } elem_num = elem - 1; if (elem > elem_ctr) { /* release connectivity array space and get next one */ if (elem_ctr > 0) { free(connect); } /* Allocate space for the connectivity array for new element block */ if (!(connect = malloc(elem_blk_parms[p_ndx].num_elem_in_blk * elem_blk_parms[p_ndx].num_nodes_per_elem * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for connectivity " "array for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } /* get connectivity array */ if (ex_get_conn(exoid, EX_ELEM_BLOCK, elem_blk_parms[p_ndx].elem_blk_id, connect, NULL, NULL) == -1) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get connectivity array for elem blk %" PRId64 " for file id %d", elem_blk_parms[p_ndx].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } elem_ctr = elem_blk_parms[p_ndx].elem_ctr; } /* For the first node of each side in side set, using a linear search (of up to num_nodes_per_elem) of the connectivity array, locate the node position in the element. The first node position and the second node position are used with a element type specific table to determine the side. */ if (connect == NULL) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: logic error. Connect pointer is null for elem blk %" PRId64 " for file id %d", elem_blk_parms[p_ndx].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } /* calculate the relative element number position in it's block*/ elem_num_pos = elem_num - (elem_blk_parms[p_ndx].elem_ctr - elem_blk_parms[p_ndx].num_elem_in_blk); /* calculate the beginning of the node list for this element by using the ss_elem_node_ndx index into the side_sets_node_index and adding the element number position * number of nodes per elem */ num_nodes_per_elem = elem_blk_parms[p_ndx].num_nodes_per_elem; for (n = 0; n < num_nodes_per_elem; n++) { /* find node in connectivity array that matches first node in side set */ if (((int_size == sizeof(int64_t)) && (ss_node0 == ((int64_t *)connect)[num_nodes_per_elem * (elem_num_pos) + n])) || ((int_size == sizeof(int)) && (ss_node0 == ((int *)connect)[num_nodes_per_elem * (elem_num_pos) + n]))) { switch (elem_blk_parms[p_ndx].elem_type_val) { case EX_EL_CIRCLE: case EX_EL_SPHERE: { /* simple case: 1st node number is same as side # */ put_side(side_sets_side_list, idx, n + 1, int_size); break; } case EX_EL_QUAD: case EX_EL_TRIANGLE: case EX_EL_TRUSS: case EX_EL_BEAM: { /* simple case: 1st node number is same as side # */ put_side(side_sets_side_list, idx, n + 1, int_size); break; } case EX_EL_TRISHELL: { /* use table to find which node to compare to next */ if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (trishell_table[0][2 * n] - 1), int_size)) { /* Assume only front or back, no edges... */ put_side(side_sets_side_list, idx, trishell_table[1][2 * n], int_size); } else if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (trishell_table[0][2 * n + 1] - 1), int_size)) { /* Assume only front or back, no edges... */ put_side(side_sets_side_list, idx, trishell_table[1][2 * n + 1], int_size); } else if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (trishell_table[0][2 * n + 2] - 1), int_size)) { /* Assume only front or back, no edges... */ put_side(side_sets_side_list, idx, trishell_table[1][2 * n + 2], int_size); } else { exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find TRIANGULAR SHELL element %" PRId64 ", node %" PRId64 " in connectivity array %" PRId64 " for file id %d", elem_num + 1, ss_node1, elem_blk_parms[p_ndx].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } break; } case EX_EL_SHELL: { /* use table to find which node to compare to next */ if (ex_int64_status(exoid) & EX_BULK_INT64_API) { num_node_per_side = ((int64_t *)ss_elem_node_ndx)[idx + 1] - ((int64_t *)ss_elem_node_ndx)[idx]; } else { num_node_per_side = ((int *)ss_elem_node_ndx)[idx + 1] - ((int *)ss_elem_node_ndx)[idx]; } if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (shell_table[0][2 * n] - 1), int_size)) { if (num_node_per_side >= 4) { /* 4- or 8-node side (front or back face) */ put_side(side_sets_side_list, idx, shell_table[1][2 * n], int_size); } else { /* 2- or 3-node side (edge of shell) */ put_side(side_sets_side_list, idx, shell_edge_table[1][2 * n], int_size); } } else if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (shell_table[0][2 * n + 1] - 1), int_size)) { if (num_node_per_side >= 4) { /* 4- or 8-node side (front or back face) */ put_side(side_sets_side_list, idx, shell_table[1][2 * n + 1], int_size); } else { /* 2- or 3-node side (edge of shell) */ put_side(side_sets_side_list, idx, shell_edge_table[1][2 * n + 1], int_size); } } else if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (shell_table[0][2 * n + 2] - 1), int_size)) { if (num_node_per_side >= 4) { /* 4- or 8-node side (front or back face) */ put_side(side_sets_side_list, idx, shell_table[1][2 * n + 2], int_size); } else { /* 2- or 3-node side (edge of shell) */ put_side(side_sets_side_list, idx, shell_edge_table[1][2 * n + 2], int_size); } } else { exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find SHELL element %" PRId64 ", node %" PRId64 " in connectivity array %" PRId64 " for file id %d", elem_num + 1, ss_node1, elem_blk_parms[p_ndx].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } break; } case EX_EL_HEX: { /* use table to find which node to compare to next */ if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (hex_table[0][3 * n] - 1), int_size)) { put_side(side_sets_side_list, idx, hex_table[1][3 * n], int_size); } else if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (hex_table[0][3 * n + 1] - 1), int_size)) { put_side(side_sets_side_list, idx, hex_table[1][3 * n + 1], int_size); } else if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (hex_table[0][3 * n + 2] - 1), int_size)) { put_side(side_sets_side_list, idx, hex_table[1][3 * n + 2], int_size); } else { exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find HEX element %" PRId64 ", node %" PRId64 " in connectivity array %" PRId64 " for file id %d", elem_num + 1, ss_node1, elem_blk_parms[p_ndx].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } break; } case EX_EL_TETRA: { /* use table to find which node to compare to next */ if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (tetra_table[0][3 * n] - 1), int_size)) { put_side(side_sets_side_list, idx, tetra_table[1][3 * n], int_size); } else if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (tetra_table[0][3 * n + 1] - 1), int_size)) { put_side(side_sets_side_list, idx, tetra_table[1][3 * n + 1], int_size); } else if (ss_node1 == get_node(connect, num_nodes_per_elem * (elem_num_pos) + (tetra_table[0][3 * n + 2] - 1), int_size)) { put_side(side_sets_side_list, idx, tetra_table[1][3 * n + 2], int_size); } else { exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find TETRA element %" PRId64 ", node %" PRId64 " in connectivity array %" PRId64 " for file id %d", elem_num + 1, ss_node1, elem_blk_parms[p_ndx].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } break; } case EX_EL_PYRAMID: { /* NOTE: PYRAMID elements in side set node lists are currently not * supported */ exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: unsupported PYRAMID element found in side " "set node list in file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } case EX_EL_WEDGE: { /* NOTE: WEDGE elements in side set node lists are currently not * supported */ exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: unsupported WEDGE element found in side set " "node list in file id %d", exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } default: { exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: %s is an unsupported element type", elem_blk_parms[p_ndx].elem_type); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } } break; /* done with this element */ } } if (n >= num_nodes_per_elem) /* did we find the node? */ { exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find element %" PRId64 ", node %" PRId64 " in element block %" PRId64 " for file id %d", elem_num + 1, ss_node0, elem_blk_parms[p_ndx].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } } /* All done: release connectivity array space, element block ids array, element block parameters array, and side set element index array */ cleanup: free(connect); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(same_elem_type); return (err_stat); }
int ex_get_side_set_node_count(int exoid, ex_entity_id side_set_id, int *side_set_node_cnt_list) { int ii, i, j; int num_side_sets, num_elem_blks, ndim; size_t tot_num_ss_elem = 0; int64_t side, elem; void_int *elem_blk_ids = NULL; void_int *ss_elem_ndx = NULL; void_int *side_set_elem_list = NULL; void_int *side_set_side_list = NULL; size_t elem_ctr; struct elem_blk_parm *elem_blk_parms = NULL; char errmsg[MAX_ERR_LENGTH]; int err_stat = EX_NOERR; ex_check_valid_file_id(exoid); exerrval = 0; /* clear error code */ /* first check if any side sets are specified */ /* inquire how many side sets have been stored */ num_side_sets = ex_inquire_int(exoid, EX_INQ_SIDE_SETS); if (num_side_sets < 0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get number of side sets in file id %d", exoid); ex_err("ex_get_side_set_node_count", errmsg, exerrval); return (EX_FATAL); } if (num_side_sets == 0) { snprintf(errmsg, MAX_ERR_LENGTH, "Warning: no side sets defined in file id %d", exoid); ex_err("ex_get_side_set_node_count", errmsg, EX_WARN); return (EX_WARN); } /* Lookup index of side set id in VAR_SS_IDS array */ ex_id_lkup(exoid, EX_SIDE_SET, side_set_id); if (exerrval != 0) { if (exerrval == EX_NULLENTITY) { snprintf(errmsg, MAX_ERR_LENGTH, "Warning: side set %" PRId64 " is NULL in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_count", errmsg, EX_NULLENTITY); return (EX_WARN); } snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to locate side set %" PRId64 " in VAR_SS_IDS array in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_count", errmsg, exerrval); return (EX_FATAL); } num_elem_blks = ex_inquire_int(exoid, EX_INQ_ELEM_BLK); if (num_elem_blks < 0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get number of element blocks in file id %d", exoid); ex_err("ex_get_side_set_node_count", errmsg, exerrval); return (EX_FATAL); } /* get the dimensionality of the coordinates; this is necessary to distinguish between 2d TRIs and 3d TRIs */ ndim = ex_inquire_int(exoid, EX_INQ_DIM); if (ndim < 0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get dimensionality in file id %d", exoid); ex_err("ex_get_side_set_node_count", errmsg, exerrval); return (EX_FATAL); } int int_size = sizeof(int); if (ex_int64_status(exoid) & EX_BULK_INT64_API) { int_size = sizeof(int64_t); } /* First determine the # of elements in the side set*/ int err; if (int_size == sizeof(int64_t)) { int64_t ss_elem = 0; int64_t ss_df = 0; err = ex_get_set_param(exoid, EX_SIDE_SET, side_set_id, &ss_elem, &ss_df); tot_num_ss_elem = ss_elem; } else { int ss_elem = 0; int ss_df = 0; err = ex_get_set_param(exoid, EX_SIDE_SET, side_set_id, &ss_elem, &ss_df); tot_num_ss_elem = ss_elem; } if (err == -1) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get number of elements in side set %" PRId64 " in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_count", errmsg, exerrval); return (EX_FATAL); } /* Allocate space for the side set element list */ { if (!(side_set_elem_list = malloc(tot_num_ss_elem * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set element " "list for file id %d", exoid); ex_err("ex_get_side_set_node_count", errmsg, exerrval); return (EX_FATAL); } /* Allocate space for the side set side list */ if (!(side_set_side_list = malloc(tot_num_ss_elem * int_size))) { free(side_set_elem_list); exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set side list " "for file id %d", exoid); ex_err("ex_get_side_set_node_count", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } if (ex_get_set(exoid, EX_SIDE_SET, side_set_id, side_set_elem_list, side_set_side_list) == -1) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get side set %" PRId64 " in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_count", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } /* Allocate space for the ss element index array */ if (!(ss_elem_ndx = malloc(tot_num_ss_elem * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set elem sort " "array for file id %d", exoid); ex_err("ex_get_side_set_node_count", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } if (int_size == sizeof(int64_t)) { /* Sort side set element list into index array - non-destructive */ int64_t *elems = (int64_t *)ss_elem_ndx; for (i = 0; i < tot_num_ss_elem; i++) { elems[i] = i; /* init index array to current position */ } ex_iqsort64(side_set_elem_list, elems, tot_num_ss_elem); } else { /* Sort side set element list into index array - non-destructive */ int *elems = (int *)ss_elem_ndx; for (i = 0; i < tot_num_ss_elem; i++) { elems[i] = i; /* init index array to current position */ } ex_iqsort(side_set_elem_list, elems, tot_num_ss_elem); } } /* Allocate space for the element block ids */ { int int_size = sizeof(int); if (ex_int64_status(exoid) & EX_IDS_INT64_API) { int_size = sizeof(int64_t); } if (!(elem_blk_ids = malloc(num_elem_blks * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for element block ids " "for file id %d", exoid); ex_err("ex_get_side_set_node_count", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } if (ex_get_ids(exoid, EX_ELEM_BLOCK, elem_blk_ids) == -1) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get element block ids in file id %d", exoid); ex_err("ex_get_side_set_node_count", errmsg, EX_MSG); err_stat = EX_FATAL; goto cleanup; } } /* Allocate space for the element block params */ if (!(elem_blk_parms = malloc(num_elem_blks * sizeof(struct elem_blk_parm)))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for element block params " "for file id %d", exoid); ex_err("ex_get_side_set_node_count", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } elem_ctr = 0; for (i = 0; i < num_elem_blks; i++) { ex_entity_id id; if (ex_int64_status(exoid) & EX_IDS_INT64_API) { id = ((int64_t *)elem_blk_ids)[i]; } else { id = ((int *)elem_blk_ids)[i]; } err_stat = ex_int_get_block_param(exoid, id, ndim, &elem_blk_parms[i]); if (err_stat != EX_NOERR) { goto cleanup; } elem_ctr += elem_blk_parms[i].num_elem_in_blk; elem_blk_parms[i].elem_ctr = elem_ctr; /* save elem number max */ } /* Finally... Create the list of node counts for each face in the * side set. */ j = 0; /* The current element block... */ for (ii = 0; ii < tot_num_ss_elem; ii++) { if (ex_int64_status(exoid) & EX_BULK_INT64_API) { i = ((int64_t *)ss_elem_ndx)[ii]; elem = ((int64_t *)side_set_elem_list)[i]; side = ((int64_t *)side_set_side_list)[i] - 1; /* Convert to 0-based sides */ } else { i = ((int *)ss_elem_ndx)[ii]; elem = ((int *)side_set_elem_list)[i]; side = ((int *)side_set_side_list)[i] - 1; /* Convert to 0-based sides */ } /* * Since the elements are being accessed in sorted, order, the * block that contains the elements must progress sequentially * from block 0 to block[num_elem_blks-1]. Once we find an element * not in this block, find a following block that contains it... */ for (; j < num_elem_blks; j++) { if (elem <= elem_blk_parms[j].elem_ctr) { break; } } if (j < num_elem_blks) { assert(side < elem_blk_parms[j].num_sides); side_set_node_cnt_list[i] = elem_blk_parms[j].num_nodes_per_side[side]; } else { exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Invalid element number %" PRId64 " found in side set %" PRId64 " in file %d", elem, side_set_id, exoid); ex_err("ex_get_side_set_node_count", errmsg, EX_MSG); err_stat = EX_FATAL; goto cleanup; } } /* All done: release connectivity array space, element block ids * array, element block parameters array, and side set element index * array */ cleanup: free(elem_blk_ids); free(elem_blk_parms); free(ss_elem_ndx); free(side_set_side_list); free(side_set_elem_list); return (err_stat); }
int ex_get_side_set_node_list(int exoid, ex_entity_id side_set_id, void_int *side_set_node_cnt_list, void_int *side_set_node_list) { size_t m; size_t i, j; int64_t elem, side; int64_t num_side_sets, num_elem_blks, num_df, ndim; int64_t tot_num_elem = 0, tot_num_ss_elem = 0, elem_num = 0; size_t connect_offset, side_num, node_pos; void_int *elem_blk_ids = NULL; void_int *connect = NULL; void_int *ss_elem_ndx = NULL; void_int *ss_elem_node_ndx = NULL; void_int *ss_parm_ndx = NULL; void_int *side_set_elem_list = NULL; void_int *side_set_side_list = NULL; size_t elem_ctr, node_ctr, elem_num_pos; size_t num_nodes_per_elem; int int_size, ids_size; int err_stat = EX_NOERR; int status; struct elem_blk_parm *elem_blk_parms = NULL; /* side to node translation tables - These tables are used to look up the side number based on the first and second node in the side/face list. The side node order is found in the original Exodus document, SAND87-2997. The element node order is found in the ExodusII document, SAND92-2137. These tables were generated by following the right-hand rule for determining the outward normal. */ /* triangle */ static int tri_table[3][3] = { /* 1 2 3 side */ {1,2,4}, {2,3,5}, {3,1,6} /* nodes */ }; /* triangle 3d */ static int tri3_table[5][7] = { /* 1 2 side */ {1,2,3,4,5,6,7}, {3,2,1,6,5,4,7}, /* nodes */ /* 3 4 5 side */ {1,2,4,0,0,0,0}, {2,3,5,0,0,0,0}, {3,1,6,0,0,0,0} /* nodes */ }; /* quad */ static int quad_table[4][3] = { /* 1 2 3 4 side */ {1,2,5}, {2,3,6}, {3,4,7}, {4,1,8} /* nodes */ }; /* shell */ static int shell_table[6][8] = { /* 1 2 side */ {1,2,3,4,5,6,7,8}, {1,4,3,2,8,7,6,5} , /* nodes */ /* 3 4 side */ {1,2,5,0,0,0,0,0}, {2,3,6,0,0,0,0,0} , /* nodes */ /* 5 6 side */ {3,4,7,0,0,0,0,0}, {4,1,8,0,0,0,0,0} /* nodes */ }; /* tetra */ static int tetra_table[4][6] = { /* 1 2 3 4 side */ {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 */ }; /* wedge */ static int wedge_table[5][8] = { /* 1 2 3 side */ {1,2,5,4,7,11,13,10}, {2,3,6,5,8,12,14,11}, {1,4,6,3,10,15,12,9}, /* 4 5 side */ {1,3,2,0,9,8,7,0}, {4,5,6,0,13,14,15,0} /* nodes */ }; /* hex */ static int hex_table[6][9] = { /* 1 2 side */ {1,2,6,5,9,14,17,13,26}, {2,3,7,6,10,15,18,14,25}, /* nodes */ /* 3 4 side */ {3,4,8,7,11,16,19,15,27}, {1,5,8,4,13,20,16,12,24}, /* nodes */ /* 5 6 side */ {1,4,3,2,12,11,10,9,22}, {5,6,7,8,17,18,19,20,23} /* nodes */ }; /* pyramid */ static int pyramid_table[5][8] = { /* 1 2 3 side */ {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 */ /* 4 5 side */ {1,5,4,0,10,13,9,0}, {1,4,3,2,9,8,7,6} /* nodes */ }; char errmsg[MAX_ERR_LENGTH]; exerrval = 0; /* clear error code */ /* first check if any side sets are specified */ /* inquire how many side sets have been stored */ num_side_sets = ex_inquire_int(exoid, EX_INQ_SIDE_SETS); if (num_side_sets < 0) { sprintf(errmsg, "Error: failed to get number of side sets in file id %d",exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); return(EX_FATAL); } if (num_side_sets == 0) { sprintf(errmsg, "Warning: no side sets defined in file id %d",exoid); ex_err("ex_get_side_set_node_list",errmsg,EX_WARN); return(EX_WARN); } /* Lookup index of side set id in VAR_SS_IDS array */ ex_id_lkup(exoid,EX_SIDE_SET,side_set_id); if (exerrval != 0) { if (exerrval == EX_NULLENTITY) { sprintf(errmsg, "Warning: side set %"PRId64" is NULL in file id %d", side_set_id,exoid); ex_err("ex_get_side_set_node_list",errmsg,EX_NULLENTITY); return (EX_WARN); } else { sprintf(errmsg, "Error: failed to locate side set %"PRId64" in VAR_SS_IDS array in file id %d", side_set_id,exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); return (EX_FATAL); } } num_elem_blks = ex_inquire_int(exoid, EX_INQ_ELEM_BLK); if (num_elem_blks < 0) { sprintf(errmsg, "Error: failed to get number of element blocks in file id %d",exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); return(EX_FATAL); } tot_num_elem = ex_inquire_int(exoid, EX_INQ_ELEM); if (tot_num_elem < 0) { sprintf(errmsg, "Error: failed to get total number of elements in file id %d",exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); return(EX_FATAL); } /* get the dimensionality of the coordinates; this is necessary to distinguish between 2d TRIs and 3d TRIs */ ndim = ex_inquire_int(exoid, EX_INQ_DIM); if (ndim < 0) { sprintf(errmsg, "Error: failed to get dimensionality in file id %d",exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); return(EX_FATAL); } int_size = sizeof(int); if (ex_int64_status(exoid) & EX_BULK_INT64_API) { int_size = sizeof(int64_t); } ids_size = sizeof(int); if (ex_int64_status(exoid) & EX_IDS_INT64_API) { ids_size = sizeof(int64_t); } /* First determine the # of elements in the side set*/ if (int_size == sizeof(int64_t)) { status = ex_get_set_param(exoid,EX_SIDE_SET, side_set_id,&tot_num_ss_elem,&num_df); } else { int tot, df; status = ex_get_set_param(exoid,EX_SIDE_SET, side_set_id,&tot,&df); tot_num_ss_elem = tot; num_df = df; } if (status != EX_NOERR) { sprintf(errmsg, "Error: failed to get number of elements in side set %"PRId64" in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); return(EX_FATAL); } /* Allocate space for the side set element list */ if (!(side_set_elem_list=malloc(tot_num_ss_elem*int_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set element list for file id %d", exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); return (EX_FATAL); } /* Allocate space for the side set side list */ if (!(side_set_side_list=malloc(tot_num_ss_elem*int_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set side list for file id %d", exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } if (ex_get_set(exoid, EX_SIDE_SET, side_set_id, side_set_elem_list, side_set_side_list) == -1) { safe_free(side_set_elem_list); safe_free(side_set_side_list); sprintf(errmsg, "Error: failed to get side set %"PRId64" in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); return (EX_FATAL); } /* Allocate space for the ss element index array */ if (!(ss_elem_ndx= malloc(tot_num_ss_elem*int_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set elem sort array for file id %d", exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } /* Sort side set element list into index array - non-destructive */ if (int_size == sizeof(int64_t)) { /* Sort side set element list into index array - non-destructive */ int64_t *elems = (int64_t*)ss_elem_ndx; for (i=0; i<tot_num_ss_elem; i++) { elems[i] = i; /* init index array to current position */ } ex_iqsort64(side_set_elem_list, ss_elem_ndx,tot_num_ss_elem); } else { /* Sort side set element list into index array - non-destructive */ int *elems = (int*)ss_elem_ndx; for (i=0; i<tot_num_ss_elem; i++) { elems[i] = i; /* init index array to current position */ } ex_iqsort(side_set_elem_list, ss_elem_ndx,tot_num_ss_elem); } /* Allocate space for the element block ids */ if (!(elem_blk_ids= malloc(num_elem_blks*ids_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for element block ids for file id %d", exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } if (ex_get_elem_blk_ids(exoid, elem_blk_ids) == -1) { sprintf(errmsg, "Error: failed to get element block ids in file id %d", exoid); ex_err("ex_get_side_set_node_list",errmsg,EX_MSG); err_stat = EX_FATAL; goto cleanup; } /* Allocate space for the element block params */ if (!(elem_blk_parms= malloc(num_elem_blks*sizeof(struct elem_blk_parm)))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for element block params for file id %d", exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } elem_ctr = 0; for (i=0; i<num_elem_blks; i++) { ex_block block; if (ids_size == sizeof(int64_t)) { block.id = ((int64_t*)elem_blk_ids)[i]; } else { block.id = ((int*)elem_blk_ids)[i]; } block.type = EX_ELEM_BLOCK; /* read in an element block parameter */ if ((ex_get_block_param (exoid, &block)) == -1) { sprintf(errmsg, "Error: failed to get element block %"PRId64" parameters in file id %d", block.id, exoid); ex_err("ex_get_side_set_node_list",errmsg,EX_MSG); err_stat = EX_FATAL; goto cleanup; } elem_blk_parms[i].num_elem_in_blk = block.num_entry; elem_blk_parms[i].num_nodes_per_elem = block.num_nodes_per_entry; elem_blk_parms[i].num_attr = block.num_attribute; elem_blk_parms[i].elem_blk_id = block.id; for (m=0; m < strlen(block.topology); m++) { elem_blk_parms[i].elem_type[m] = toupper(block.topology[m]); } elem_blk_parms[i].elem_type[m] = '\0'; if (strncmp(elem_blk_parms[i].elem_type,"CIRCLE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_CIRCLE; /* set side set node stride */ elem_blk_parms[i].num_nodes_per_side[0] = 1; } else if (strncmp(elem_blk_parms[i].elem_type,"SPHERE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_SPHERE; /* set side set node stride */ elem_blk_parms[i].num_nodes_per_side[0] = 1; } else if (strncmp(elem_blk_parms[i].elem_type,"QUAD",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_QUAD; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 4) elem_blk_parms[i].num_nodes_per_side[0] = 2; else if (elem_blk_parms[i].num_nodes_per_elem == 5) elem_blk_parms[i].num_nodes_per_side[0] = 2; else elem_blk_parms[i].num_nodes_per_side[0] = 3; } else if (strncmp(elem_blk_parms[i].elem_type,"TRIANGLE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_TRIANGLE; /* set default side set node stride */ if (ndim == 2) /* 2d TRIs */ { if (elem_blk_parms[i].num_nodes_per_elem == 3) elem_blk_parms[i].num_nodes_per_side[0] = 2; else elem_blk_parms[i].num_nodes_per_side[0] = 3; } else if (ndim == 3) /* 3d TRIs */ { if (elem_blk_parms[i].num_nodes_per_elem == 3) elem_blk_parms[i].num_nodes_per_side[0] = 3; else elem_blk_parms[i].num_nodes_per_side[0] = 6; } } else if (strncmp(elem_blk_parms[i].elem_type,"SHELL",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_SHELL; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 2) /* KLUDGE for 2D Shells*/ elem_blk_parms[i].num_nodes_per_side[0] = 2; else if (elem_blk_parms[i].num_nodes_per_elem == 4) elem_blk_parms[i].num_nodes_per_side[0] = 4; else elem_blk_parms[i].num_nodes_per_side[0] = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"HEX",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_HEX; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 8) /* 8-node bricks */ elem_blk_parms[i].num_nodes_per_side[0] = 4; else if (elem_blk_parms[i].num_nodes_per_elem == 9) /* 9-node bricks */ elem_blk_parms[i].num_nodes_per_side[0] = 4; else if (elem_blk_parms[i].num_nodes_per_elem == 12) /* HEXSHELLS */ elem_blk_parms[i].num_nodes_per_side[0] = 4; else if (elem_blk_parms[i].num_nodes_per_elem == 27) /* 27-node bricks */ elem_blk_parms[i].num_nodes_per_side[0] = 9; else elem_blk_parms[i].num_nodes_per_side[0] = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"TETRA",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_TETRA; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 4) elem_blk_parms[i].num_nodes_per_side[0] = 3; else if (elem_blk_parms[i].num_nodes_per_elem == 8) elem_blk_parms[i].num_nodes_per_side[0] = 4; else elem_blk_parms[i].num_nodes_per_side[0] = 6; } else if (strncmp(elem_blk_parms[i].elem_type,"WEDGE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_WEDGE; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 6) elem_blk_parms[i].num_nodes_per_side[0] = 4; else elem_blk_parms[i].num_nodes_per_side[0] = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"PYRAMID",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_PYRAMID; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 5) elem_blk_parms[i].num_nodes_per_side[0] = 4; else elem_blk_parms[i].num_nodes_per_side[0] = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"BEAM",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_BEAM; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 2) elem_blk_parms[i].num_nodes_per_side[0] = 2; else elem_blk_parms[i].num_nodes_per_side[0] = 3; } else if ( (strncmp(elem_blk_parms[i].elem_type,"TRUSS",3) == 0) || (strncmp(elem_blk_parms[i].elem_type,"BAR",3) == 0) || (strncmp(elem_blk_parms[i].elem_type,"EDGE",3) == 0) ) { elem_blk_parms[i].elem_type_val = EX_EL_TRUSS; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 2) elem_blk_parms[i].num_nodes_per_side[0] = 2; else elem_blk_parms[i].num_nodes_per_side[0] = 3; } else if (strncmp(elem_blk_parms[i].elem_type,"NULL",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_NULL_ELEMENT; elem_blk_parms[i].num_nodes_per_side[0] = 0; elem_blk_parms[i].num_elem_in_blk = 0; } else { /* unsupported element type; no problem if no sides specified for this element block */ elem_blk_parms[i].elem_type_val = EX_EL_UNK; elem_blk_parms[i].num_nodes_per_side[0] = 0; } elem_blk_parms[i].elem_blk_id = block.id; /* save id */ elem_ctr += elem_blk_parms[i].num_elem_in_blk; elem_blk_parms[i].elem_ctr = elem_ctr; /* save elem number max */ } /* Allocate space for the ss element to element block parameter index array */ if (!(ss_parm_ndx=malloc(tot_num_ss_elem*int_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set elem parms index for file id %d", exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } /* Allocate space for the ss element to node list index array */ if (!(ss_elem_node_ndx=malloc(tot_num_ss_elem*int_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set elem to node index for file id %d", exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } /* Build side set element to node list index and side set element parameter index. */ node_ctr = 0; for (i=0; i<tot_num_ss_elem; i++) { if (ex_int64_status(exoid) & EX_BULK_INT64_API) { elem = ((int64_t*)side_set_elem_list)[i]; side = ((int64_t*)side_set_side_list)[i]; } else { elem = ((int*)side_set_elem_list)[i]; side = ((int*)side_set_side_list)[i]; } for (j=0; j<num_elem_blks; j++) { if (elem_blk_parms[j].elem_type_val != EX_EL_NULL_ELEMENT) if (elem <= elem_blk_parms[j].elem_ctr) break; } if (j >= num_elem_blks) { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid element number %"PRId64" found in side set %"PRId64" in file %d", elem, side_set_id, exoid); ex_err("ex_get_side_set_node_list",errmsg,EX_MSG); err_stat = EX_FATAL; goto cleanup; } if (int_size == sizeof(int64_t)) { ((int64_t*)ss_parm_ndx)[i] = j; /* assign parameter block index */ ((int64_t*)ss_elem_node_ndx)[i] = node_ctr; /* assign node list index */ } else { ((int*)ss_parm_ndx)[i] = j; /* assign parameter block index */ ((int*)ss_elem_node_ndx)[i] = node_ctr; /* assign node list index */ } /* Update node_ctr (which points to next node in chain */ /* WEDGEs with 3 node sides (side 4 or 5) are special cases */ if (elem_blk_parms[j].elem_type_val == EX_EL_WEDGE && (side == 4 || side == 5)) { if (elem_blk_parms[j].num_nodes_per_elem == 6) node_ctr += 3; /* 3 node side */ else node_ctr += 6; /* 6 node side */ } /* PYRAMIDSs with 3 node sides (sides 1,2,3,4) are also special */ else if (elem_blk_parms[j].elem_type_val == EX_EL_PYRAMID && (side < 5)) { if (elem_blk_parms[j].num_nodes_per_elem == 5) node_ctr += 3; /* 3 node side */ else node_ctr += 6; /* 6 node side */ } /* side numbers 3,4,5,6 for SHELLs are also special */ else if (elem_blk_parms[j].elem_type_val == EX_EL_SHELL && (side > 2 )) { if (elem_blk_parms[j].num_nodes_per_elem == 4) node_ctr += 2; /* 2 node side */ else node_ctr += 3; /* 3 node side */ } /* side numbers 3,4,5 for 3d TRIs are also special */ else if (elem_blk_parms[j].elem_type_val == EX_EL_TRIANGLE && ndim == 3 && side > 2 ) { if (elem_blk_parms[j].num_nodes_per_elem == 3) /* 3-node TRI */ node_ctr += 2; /* 2 node side */ else /* 6-node TRI */ node_ctr += 3; /* 3 node side */ } else /* all other element types */ node_ctr += elem_blk_parms[j].num_nodes_per_side[0]; } /* All setup, ready to go ... */ elem_ctr=0; for (j=0; j < tot_num_ss_elem; j++) { int64_t elem_ndx; size_t parm_ndx; if (ex_int64_status(exoid) & EX_BULK_INT64_API) { elem_ndx = ((int64_t*)ss_elem_ndx)[j]; elem = ((int64_t*)side_set_elem_list)[elem_ndx]; side = ((int64_t*)side_set_side_list)[elem_ndx]; parm_ndx = ((int64_t*)ss_parm_ndx)[elem_ndx]; } else { elem_ndx = ((int*)ss_elem_ndx)[j]; elem = ((int*)side_set_elem_list)[elem_ndx]; side = ((int*)side_set_side_list)[elem_ndx]; parm_ndx = ((int*)ss_parm_ndx)[elem_ndx]; } if (elem > elem_ctr) { /* release connectivity array space and get next one */ if (elem_ctr > 0) { safe_free(connect); } /* Allocate space for the connectivity array for new element block */ if (!(connect=malloc(elem_blk_parms[parm_ndx].num_elem_in_blk* elem_blk_parms[parm_ndx].num_nodes_per_elem* int_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for connectivity array for file id %d", exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } /* get connectivity array */ if (ex_get_elem_conn(exoid, elem_blk_parms[parm_ndx].elem_blk_id, connect) == -1) { sprintf(errmsg, "Error: failed to allocate space for connectivity array for file id %d", exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } elem_ctr = elem_blk_parms[parm_ndx].elem_ctr; } /* For each side in side set, use the appropriate lookup table to determine the nodes from the connect array. */ elem_num = elem-1;/* element number 0-based*/ /* calculate the relative element number position in it's block*/ elem_num_pos = elem_num - (elem_blk_parms[parm_ndx].elem_ctr - elem_blk_parms[parm_ndx].num_elem_in_blk); /* calculate the beginning of the node list for this element by using the ss_elem_node_ndx index into the side_sets_node_index and adding the element number position * number of nodes per elem */ num_nodes_per_elem = elem_blk_parms[parm_ndx].num_nodes_per_elem; connect_offset = num_nodes_per_elem*elem_num_pos; side_num = side-1; if (int_size == sizeof(int64_t)) { node_pos = ((int64_t*)ss_elem_node_ndx)[elem_ndx]; } else { node_pos = ((int*)ss_elem_node_ndx)[elem_ndx]; } switch (elem_blk_parms[parm_ndx].elem_type_val) { case EX_EL_CIRCLE: case EX_EL_SPHERE: { /* Note: no side-node lookup table is used for this simple case */ get_nodes(exoid, side_set_node_list, node_pos, connect, connect_offset); set_count(exoid, side_set_node_cnt_list, elem_ndx, 1); /* 1 node object */ break; } case EX_EL_TRUSS: case EX_EL_BEAM: { /* Note: no side-node lookup table is used for this simple case */ for (i=0; i < num_nodes_per_elem; i++) { get_nodes(exoid, side_set_node_list, node_pos+i, connect, connect_offset+i); } set_count(exoid, side_set_node_cnt_list, elem_ndx, num_nodes_per_elem); break; } case EX_EL_TRIANGLE: { if (side_num+1 < 1 || side_num+1 > 5) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid triangle edge number %"ST_ZU" in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } if (ndim == 2) /* 2d TRIs */ { get_nodes(exoid, side_set_node_list, node_pos, connect, connect_offset+tri_table[side_num][0]-1); get_nodes(exoid, side_set_node_list, node_pos+1, connect, connect_offset+tri_table[side_num][1]-1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 2); /* 2 node object */ if (num_nodes_per_elem > 3) /* 6-node TRI */ { get_nodes(exoid, side_set_node_list, node_pos+2, connect, connect_offset+tri_table[side_num][2]-1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node object */ } } else if (ndim == 3) /* 3d TRIs */ { get_nodes(exoid, side_set_node_list, node_pos, connect, connect_offset+tri3_table[side_num][0]-1); get_nodes(exoid, side_set_node_list, node_pos+1, connect, connect_offset+tri3_table[side_num][1]-1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 2); /* 2 node object */ if (side_num+1 <= 2) /* 3- or 6-node face */ { if (num_nodes_per_elem == 3) /* 3-node face */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node object */ get_nodes(exoid, side_set_node_list, node_pos+2, connect, connect_offset+tri3_table[side_num][2]-1); } else /* 6-node face */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 6); /* 6 node object */ get_nodes(exoid, side_set_node_list, node_pos+2, connect, connect_offset+tri3_table[side_num][2]-1); get_nodes(exoid, side_set_node_list, node_pos+3, connect, connect_offset+tri3_table[side_num][3]-1); get_nodes(exoid, side_set_node_list, node_pos+4, connect, connect_offset+tri3_table[side_num][4]-1); get_nodes(exoid, side_set_node_list, node_pos+5, connect, connect_offset+tri3_table[side_num][5]-1); } } else /* 2- or 3-node edge */ { if (num_nodes_per_elem > 3) /* 3-node edge */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node object */ get_nodes(exoid, side_set_node_list, node_pos+2, connect, connect_offset+tri3_table[side_num][2]-1); } } } break; } case EX_EL_QUAD: { if (side_num+1 < 1 || side_num+1 > 4) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid quad edge number %"ST_ZU" in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos+0, connect, connect_offset+quad_table[side_num][0]-1); get_nodes(exoid, side_set_node_list, node_pos+1, connect, connect_offset+quad_table[side_num][1]-1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 2); /* 2 node object */ if (num_nodes_per_elem > 5) { set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node object */ get_nodes(exoid, side_set_node_list, node_pos+2, connect, connect_offset+quad_table[side_num][2]-1); } break; } case EX_EL_SHELL: { if (side_num+1 < 1 || side_num+1 > 6) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid shell face number %"ST_ZU" in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos+0, connect, connect_offset+shell_table[side_num][0]-1); get_nodes(exoid, side_set_node_list, node_pos+1, connect, connect_offset+shell_table[side_num][1]-1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 2); /* 2 node object */ if (num_nodes_per_elem > 2) /*** KLUDGE for 2D shells ***/ { if (side_num+1 <= 2) /* 4-node face */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 4); /* 4 node object */ get_nodes(exoid, side_set_node_list, node_pos+2, connect, connect_offset+shell_table[side_num][2]-1); get_nodes(exoid, side_set_node_list, node_pos+3, connect, connect_offset+shell_table[side_num][3]-1); } } if (num_nodes_per_elem == 8) { if (side_num+1 <= 2) /* 8-node face */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 8); /* 8 node object */ get_nodes(exoid, side_set_node_list, node_pos+4, connect, connect_offset+shell_table[side_num][4]-1); get_nodes(exoid, side_set_node_list, node_pos+5, connect, connect_offset+shell_table[side_num][5]-1); get_nodes(exoid, side_set_node_list, node_pos+6, connect, connect_offset+shell_table[side_num][6]-1); get_nodes(exoid, side_set_node_list, node_pos+7, connect, connect_offset+shell_table[side_num][7]-1); } else { set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node edge */ get_nodes(exoid, side_set_node_list, node_pos+2, connect, connect_offset+shell_table[side_num][2]-1); } } break; } case EX_EL_TETRA: { if (side_num+1 < 1 || side_num+1 > 4) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid tetra face number %"ST_ZU" in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos+0, connect, connect_offset+tetra_table[side_num][0]-1); get_nodes(exoid, side_set_node_list, node_pos+1, connect, connect_offset+tetra_table[side_num][1]-1); get_nodes(exoid, side_set_node_list, node_pos+2, connect, connect_offset+tetra_table[side_num][2]-1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node object */ if (num_nodes_per_elem == 8) { set_count(exoid, side_set_node_cnt_list, elem_ndx, 4); /* 4 node object */ get_nodes(exoid, side_set_node_list, node_pos+3, connect, connect_offset+tetra_table[side_num][3]-1); } else if (num_nodes_per_elem > 8) { set_count(exoid, side_set_node_cnt_list, elem_ndx, 6); /* 6 node object */ get_nodes(exoid, side_set_node_list, node_pos+3, connect, connect_offset+tetra_table[side_num][3]-1); get_nodes(exoid, side_set_node_list, node_pos+4, connect, connect_offset+tetra_table[side_num][4]-1); get_nodes(exoid, side_set_node_list, node_pos+5, connect, connect_offset+tetra_table[side_num][5]-1); } break; } case EX_EL_WEDGE: { if (side_num+1 < 1 || side_num+1 > 5) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid wedge face number %"ST_ZU" in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+wedge_table[side_num][0]-1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+wedge_table[side_num][1]-1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+wedge_table[side_num][2]-1); if (wedge_table[side_num][3] == 0) { /* degenerate side? */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node side */ } else { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+wedge_table[side_num][3]-1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 4); /* 4 node side */ } if (num_nodes_per_elem > 6) { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+wedge_table[side_num][4]-1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+wedge_table[side_num][5]-1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+wedge_table[side_num][6]-1); if (wedge_table[side_num][7] == 0) /* degenerate side? */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 7); /* 6 node side */ else { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+wedge_table[side_num][7]-1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 8); /* 8 node side */ } } break; } case EX_EL_PYRAMID: { if (side_num+1 < 1 || side_num+1 > 5) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid pyramid face number %"ST_ZU" in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+pyramid_table[side_num][0]-1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+pyramid_table[side_num][1]-1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+pyramid_table[side_num][2]-1); if (pyramid_table[side_num][3] == 0) { /* degenerate side? */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node side */ } else { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+pyramid_table[side_num][3]-1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 4); /* 4 node side */ } if (num_nodes_per_elem > 5) { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+pyramid_table[side_num][4]-1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+pyramid_table[side_num][5]-1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+pyramid_table[side_num][6]-1); if (pyramid_table[side_num][7] == 0) /* degenerate side? */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 7); /* 6 node side */ else { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset+pyramid_table[side_num][7]-1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 8); /* 8 node side */ } } break; } case EX_EL_HEX: { if (side_num+1 < 1 || side_num+1 > 6) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid hex face number %"ST_ZU" in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); err_stat = EX_FATAL; goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos+0, connect, connect_offset+hex_table[side_num][0]-1); get_nodes(exoid, side_set_node_list, node_pos+1, connect, connect_offset+hex_table[side_num][1]-1); get_nodes(exoid, side_set_node_list, node_pos+2, connect, connect_offset+hex_table[side_num][2]-1); get_nodes(exoid, side_set_node_list, node_pos+3, connect, connect_offset+hex_table[side_num][3]-1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 4); /* 4 node object */ if (num_nodes_per_elem > 12) /* more nodes than HEXSHELL */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 8); /* 8 node object */ get_nodes(exoid, side_set_node_list, node_pos+4, connect, connect_offset+hex_table[side_num][4]-1); get_nodes(exoid, side_set_node_list, node_pos+5, connect, connect_offset+hex_table[side_num][5]-1); get_nodes(exoid, side_set_node_list, node_pos+6, connect, connect_offset+hex_table[side_num][6]-1); get_nodes(exoid, side_set_node_list, node_pos+7, connect, connect_offset+hex_table[side_num][7]-1); } if (num_nodes_per_elem == 27) /* 27-node brick */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 9); /* 9 node object */ get_nodes(exoid, side_set_node_list, node_pos+8, connect, connect_offset+hex_table[side_num][8]-1); } break; } default: { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: %s is an unsupported element type", elem_blk_parms[parm_ndx].elem_type); ex_err("ex_get_side_set_node_list",errmsg,exerrval); return(EX_FATAL); } } } /* All done: release connectivity array space, element block ids array, element block parameters array, and side set element index array */ cleanup: safe_free(connect); safe_free(ss_parm_ndx); safe_free(elem_blk_ids); safe_free(elem_blk_parms); safe_free(ss_elem_ndx); safe_free(ss_elem_node_ndx); safe_free(side_set_side_list); safe_free(side_set_elem_list); return(err_stat); }
int ex_get_side_set_node_list(int exoid, ex_entity_id side_set_id, void_int *side_set_node_cnt_list, void_int *side_set_node_list) { size_t i, j; int64_t elem, side; int64_t num_side_sets, num_elem_blks, num_df, ndim; int64_t tot_num_elem = 0, tot_num_ss_elem = 0, elem_num = 0; size_t connect_offset, side_num, node_pos; void_int *elem_blk_ids = NULL; void_int *connect = NULL; void_int *ss_elem_ndx = NULL; void_int *ss_elem_node_ndx = NULL; void_int *ss_parm_ndx = NULL; void_int *side_set_elem_list = NULL; void_int *side_set_side_list = NULL; size_t elem_ctr, node_ctr, elem_num_pos; size_t num_nodes_per_elem; int int_size, ids_size; int err_stat = EX_NOERR; int status; struct elem_blk_parm *elem_blk_parms = NULL; /* side to node translation tables - These tables are used to look up the side number based on the first and second node in the side/face list. The side node order is found in the original Exodus document, SAND87-2997. The element node order is found in the ExodusII document, SAND92-2137. These tables were generated by following the right-hand rule for determining the outward normal. */ /* triangle */ static int tri_table[3][3] = { {1, 2, 4}, /* side 1 */ {2, 3, 5}, /* side 2 */ {3, 1, 6} /* side 3 */ }; /* triangle 3d */ static int tri3_table[5][7] = { {1, 2, 3, 4, 5, 6, 7}, /* side 1 (face) */ {3, 2, 1, 6, 5, 4, 7}, /* side 2 (face) */ {1, 2, 4, 0, 0, 0, 0}, /* side 3 (edge) */ {2, 3, 5, 0, 0, 0, 0}, /* side 4 (edge) */ {3, 1, 6, 0, 0, 0, 0} /* side 5 (edge) */ }; /* quad */ static int quad_table[4][3] = { {1, 2, 5}, /* side 1 */ {2, 3, 6}, /* side 2 */ {3, 4, 7}, /* side 3 */ {4, 1, 8} /* side 4 */ }; /* shell */ static int shell_table[6][9] = { {1, 2, 3, 4, 5, 6, 7, 8, 9}, /* side 1 (face) */ {1, 4, 3, 2, 8, 7, 6, 5, 9}, /* side 2 (face) */ {1, 2, 5, 0, 0, 0, 0, 0, 0}, /* side 3 (edge) */ {2, 3, 6, 0, 0, 0, 0, 0, 0}, /* side 4 (edge) */ {3, 4, 7, 0, 0, 0, 0, 0, 0}, /* side 5 (edge) */ {4, 1, 8, 0, 0, 0, 0, 0, 0} /* side 6 (edge) */ }; /* tetra */ static int tetra_table[4][7] = { {1, 2, 4, 5, 9, 8, 14}, /* Side 1 nodes */ {2, 3, 4, 6, 10, 9, 12}, /* Side 2 nodes */ {1, 4, 3, 8, 10, 7, 13}, /* Side 3 nodes */ {1, 3, 2, 7, 6, 5, 11} /* Side 4 nodes */ }; /* wedge */ /* wedge 6 or 7 */ static int wedge6_table[5][4] = { {1, 2, 5, 4}, /* Side 1 nodes -- quad */ {2, 3, 6, 5}, /* Side 2 nodes -- quad */ {1, 4, 6, 3}, /* Side 3 nodes -- quad */ {1, 3, 2, 0}, /* Side 4 nodes -- triangle */ {4, 5, 6, 0} /* Side 5 nodes -- triangle */ }; /* wedge 15 or 16 */ static int wedge15_table[5][8] = { {1, 2, 5, 4, 7, 11, 13, 10}, /* Side 1 nodes -- quad */ {2, 3, 6, 5, 8, 12, 14, 11}, /* Side 2 nodes -- quad */ {1, 4, 6, 3, 10, 15, 12, 9}, /* Side 3 nodes -- quad */ {1, 3, 2, 9, 8, 7, 0, 0}, /* Side 4 nodes -- triangle */ {4, 5, 6, 13, 14, 15, 0, 0} /* Side 5 nodes -- triangle */ }; /* wedge 20 */ static int wedge20_table[5][9] = { {1, 2, 5, 4, 7, 11, 13, 10, 20}, /* Side 1 nodes -- quad */ {2, 3, 6, 5, 8, 12, 14, 11, 18}, /* Side 2 nodes -- quad */ {1, 4, 6, 3, 10, 15, 12, 9, 19}, /* Side 3 nodes -- quad */ {1, 3, 2, 9, 8, 7, 16, 0, 0}, /* Side 4 nodes -- triangle */ {4, 5, 6, 13, 14, 15, 17, 0, 0} /* Side 5 nodes -- triangle */ }; /* wedge 21 */ static int wedge21_table[5][9] = { {1, 2, 5, 4, 7, 11, 13, 10, 21}, /* Side 1 nodes -- quad */ {2, 3, 6, 5, 8, 12, 14, 11, 19}, /* Side 2 nodes -- quad */ {1, 4, 6, 3, 10, 15, 12, 9, 20}, /* Side 3 nodes -- quad */ {1, 3, 2, 9, 8, 7, 17, 0, 0}, /* Side 4 nodes -- triangle */ {4, 5, 6, 13, 14, 15, 18, 0, 0} /* Side 5 nodes -- triangle */ }; /* wedge 18 */ static int wedge18_table[5][9] = { {1, 2, 5, 4, 7, 11, 13, 10, 16}, /* Side 1 nodes -- quad */ {2, 3, 6, 5, 8, 12, 14, 11, 17}, /* Side 2 nodes -- quad */ {1, 4, 6, 3, 10, 15, 12, 9, 18}, /* Side 3 nodes -- quad */ {1, 3, 2, 9, 8, 7, 0, 0, 0}, /* Side 4 nodes -- triangle */ {4, 5, 6, 13, 14, 15, 0, 0, 0} /* Side 5 nodes -- triangle */ }; /* hex */ static int hex_table[6][9] = { {1, 2, 6, 5, 9, 14, 17, 13, 26}, /* side 1 */ {2, 3, 7, 6, 10, 15, 18, 14, 25}, /* side 2 */ {3, 4, 8, 7, 11, 16, 19, 15, 27}, /* side 3 */ {1, 5, 8, 4, 13, 20, 16, 12, 24}, /* side 4 */ {1, 4, 3, 2, 12, 11, 10, 9, 22}, /* side 5 */ {5, 6, 7, 8, 17, 18, 19, 20, 23} /* side 6 */ }; /* pyramid */ static int pyramid_table[5][9] = { {1, 2, 5, 0, 6, 11, 10, 0, 15}, /* side 1 (tri) */ {2, 3, 5, 0, 7, 12, 11, 0, 16}, /* side 2 (tri) */ {3, 4, 5, 0, 8, 13, 12, 0, 17}, /* side 3 (tri) */ {1, 5, 4, 0, 10, 13, 9, 0, 18}, /* side 4 (tri) */ {1, 4, 3, 2, 9, 8, 7, 6, 14} /* side 5 (quad) */ }; char errmsg[MAX_ERR_LENGTH]; exerrval = 0; /* clear error code */ /* first check if any side sets are specified */ /* inquire how many side sets have been stored */ num_side_sets = ex_inquire_int(exoid, EX_INQ_SIDE_SETS); if (num_side_sets < 0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get number of side sets in file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); return (EX_FATAL); } if (num_side_sets == 0) { snprintf(errmsg, MAX_ERR_LENGTH, "Warning: no side sets defined in file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, EX_WARN); return (EX_WARN); } /* Lookup index of side set id in VAR_SS_IDS array */ ex_id_lkup(exoid, EX_SIDE_SET, side_set_id); if (exerrval != 0) { if (exerrval == EX_NULLENTITY) { snprintf(errmsg, MAX_ERR_LENGTH, "Warning: side set %" PRId64 " is NULL in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_list", errmsg, EX_NULLENTITY); return (EX_WARN); } snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to locate side set %" PRId64 " in VAR_SS_IDS array in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); return (EX_FATAL); } num_elem_blks = ex_inquire_int(exoid, EX_INQ_ELEM_BLK); if (num_elem_blks < 0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get number of element blocks in file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); return (EX_FATAL); } tot_num_elem = ex_inquire_int(exoid, EX_INQ_ELEM); if (tot_num_elem < 0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get total number of elements in file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); return (EX_FATAL); } /* get the dimensionality of the coordinates; this is necessary to distinguish between 2d TRIs and 3d TRIs */ ndim = ex_inquire_int(exoid, EX_INQ_DIM); if (ndim < 0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get dimensionality in file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); return (EX_FATAL); } int_size = sizeof(int); if (ex_int64_status(exoid) & EX_BULK_INT64_API) { int_size = sizeof(int64_t); } ids_size = sizeof(int); if (ex_int64_status(exoid) & EX_IDS_INT64_API) { ids_size = sizeof(int64_t); } /* First determine the # of elements in the side set*/ if (int_size == sizeof(int64_t)) { status = ex_get_set_param(exoid, EX_SIDE_SET, side_set_id, &tot_num_ss_elem, &num_df); } else { int tot, df; status = ex_get_set_param(exoid, EX_SIDE_SET, side_set_id, &tot, &df); tot_num_ss_elem = tot; num_df = df; } if (status != EX_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get number of elements in side set %" PRId64 " in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); return (EX_FATAL); } /* Allocate space for the side set element list */ if (!(side_set_elem_list = malloc(tot_num_ss_elem * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set element list " "for file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); return (EX_FATAL); } /* Allocate space for the side set side list */ if (!(side_set_side_list = malloc(tot_num_ss_elem * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set side list for file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } if (ex_get_set(exoid, EX_SIDE_SET, side_set_id, side_set_elem_list, side_set_side_list) == -1) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get side set %" PRId64 " in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } /* Allocate space for the ss element index array */ if (!(ss_elem_ndx = malloc(tot_num_ss_elem * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set elem sort " "array for file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } /* Sort side set element list into index array - non-destructive */ if (int_size == sizeof(int64_t)) { /* Sort side set element list into index array - non-destructive */ int64_t *elems = (int64_t *)ss_elem_ndx; for (i = 0; i < tot_num_ss_elem; i++) { elems[i] = i; /* init index array to current position */ } ex_iqsort64(side_set_elem_list, ss_elem_ndx, tot_num_ss_elem); } else { /* Sort side set element list into index array - non-destructive */ int *elems = (int *)ss_elem_ndx; for (i = 0; i < tot_num_ss_elem; i++) { elems[i] = i; /* init index array to current position */ } ex_iqsort(side_set_elem_list, ss_elem_ndx, tot_num_ss_elem); } /* Allocate space for the element block ids */ if (!(elem_blk_ids = malloc(num_elem_blks * ids_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for element block ids for file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } if (ex_get_ids(exoid, EX_ELEM_BLOCK, elem_blk_ids) == -1) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get element block ids in file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, EX_MSG); err_stat = EX_FATAL; goto cleanup; } /* Allocate space for the element block params */ if (!(elem_blk_parms = malloc(num_elem_blks * sizeof(struct elem_blk_parm)))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for element block params " "for file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } elem_ctr = 0; for (i = 0; i < num_elem_blks; i++) { ex_entity_id id; if (ids_size == sizeof(int64_t)) { id = ((int64_t *)elem_blk_ids)[i]; } else { id = ((int *)elem_blk_ids)[i]; } err_stat = ex_int_get_block_param(exoid, id, ndim, &elem_blk_parms[i]); if (err_stat != EX_NOERR) { goto cleanup; } elem_ctr += elem_blk_parms[i].num_elem_in_blk; elem_blk_parms[i].elem_ctr = elem_ctr; /* save elem number max */ } /* Allocate space for the ss element to element block parameter index array */ if (!(ss_parm_ndx = malloc(tot_num_ss_elem * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set elem parms " "index for file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } /* Allocate space for the ss element to node list index array */ if (!(ss_elem_node_ndx = malloc(tot_num_ss_elem * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set elem to node " "index for file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } /* Build side set element to node list index and side set element parameter index. */ node_ctr = 0; for (i = 0; i < tot_num_ss_elem; i++) { if (ex_int64_status(exoid) & EX_BULK_INT64_API) { elem = ((int64_t *)side_set_elem_list)[i]; side = ((int64_t *)side_set_side_list)[i]; } else { elem = ((int *)side_set_elem_list)[i]; side = ((int *)side_set_side_list)[i]; } for (j = 0; j < num_elem_blks; j++) { if (elem_blk_parms[j].elem_type_val != EX_EL_NULL_ELEMENT) { if (elem <= elem_blk_parms[j].elem_ctr) { break; } } } if (j >= num_elem_blks) { exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Invalid element number %" PRId64 " found in side set %" PRId64 " in file %d", elem, side_set_id, exoid); ex_err("ex_get_side_set_node_list", errmsg, EX_MSG); err_stat = EX_FATAL; goto cleanup; } if (int_size == sizeof(int64_t)) { ((int64_t *)ss_parm_ndx)[i] = j; /* assign parameter block index */ ((int64_t *)ss_elem_node_ndx)[i] = node_ctr; /* assign node list index */ } else { ((int *)ss_parm_ndx)[i] = j; /* assign parameter block index */ ((int *)ss_elem_node_ndx)[i] = node_ctr; /* assign node list index */ } /* Update node_ctr (which points to next node in chain */ node_ctr += elem_blk_parms[j].num_nodes_per_side[side - 1]; } /* All setup, ready to go ... */ elem_ctr = 0; for (j = 0; j < tot_num_ss_elem; j++) { int64_t elem_ndx; size_t parm_ndx; if (ex_int64_status(exoid) & EX_BULK_INT64_API) { elem_ndx = ((int64_t *)ss_elem_ndx)[j]; elem = ((int64_t *)side_set_elem_list)[elem_ndx]; side = ((int64_t *)side_set_side_list)[elem_ndx]; parm_ndx = ((int64_t *)ss_parm_ndx)[elem_ndx]; } else { elem_ndx = ((int *)ss_elem_ndx)[j]; elem = ((int *)side_set_elem_list)[elem_ndx]; side = ((int *)side_set_side_list)[elem_ndx]; parm_ndx = ((int *)ss_parm_ndx)[elem_ndx]; } if (elem > elem_ctr) { /* release connectivity array space and get next one */ if (elem_ctr > 0) { free(connect); } /* Allocate space for the connectivity array for new element block */ if (!(connect = malloc(elem_blk_parms[parm_ndx].num_elem_in_blk * elem_blk_parms[parm_ndx].num_nodes_per_elem * int_size))) { exerrval = EX_MEMFAIL; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for connectivity " "array for file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } /* get connectivity array */ if (ex_get_conn(exoid, EX_ELEM_BLOCK, elem_blk_parms[parm_ndx].elem_blk_id, connect, NULL, NULL) == -1) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for connectivity " "array for file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } elem_ctr = elem_blk_parms[parm_ndx].elem_ctr; } if (connect == NULL) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: internal error -- connect pointer is NULL for file id %d", exoid); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } /* For each side in side set, use the appropriate lookup table to determine the nodes from the connect array. */ elem_num = elem - 1; /* element number 0-based*/ /* calculate the relative element number position in it's block*/ elem_num_pos = elem_num - (elem_blk_parms[parm_ndx].elem_ctr - elem_blk_parms[parm_ndx].num_elem_in_blk); /* calculate the beginning of the node list for this element by using the ss_elem_node_ndx index into the side_sets_node_index and adding the element number position * number of nodes per elem */ num_nodes_per_elem = elem_blk_parms[parm_ndx].num_nodes_per_elem; connect_offset = num_nodes_per_elem * elem_num_pos; side_num = side - 1; if (int_size == sizeof(int64_t)) { node_pos = ((int64_t *)ss_elem_node_ndx)[elem_ndx]; } else { node_pos = ((int *)ss_elem_node_ndx)[elem_ndx]; } switch (elem_blk_parms[parm_ndx].elem_type_val) { case EX_EL_CIRCLE: case EX_EL_SPHERE: { /* Note: no side-node lookup table is used for this simple case */ get_nodes(exoid, side_set_node_list, node_pos, connect, connect_offset); set_count(exoid, side_set_node_cnt_list, elem_ndx, 1); /* 1 node object */ break; } case EX_EL_TRUSS: case EX_EL_BEAM: { /* Note: no side-node lookup table is used for this simple case */ for (i = 0; i < num_nodes_per_elem; i++) { get_nodes(exoid, side_set_node_list, node_pos + i, connect, connect_offset + i); } set_count(exoid, side_set_node_cnt_list, elem_ndx, num_nodes_per_elem); break; } case EX_EL_TRIANGLE: { if (ndim == 2) { /* 2d TRIs */ if (check_valid_side(side_num, 3, "triangle", exoid) != EX_NOERR) { goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos, connect, connect_offset + tri_table[side_num][0] - 1); get_nodes(exoid, side_set_node_list, node_pos + 1, connect, connect_offset + tri_table[side_num][1] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 2); /* 2 node object */ if (num_nodes_per_elem > 3) /* 6-node TRI */ { get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + tri_table[side_num][2] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node object */ } } else if (ndim == 3) { /* 3d TRIs */ if (check_valid_side(side_num, 5, "triangle", exoid) != EX_NOERR) { goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos, connect, connect_offset + tri3_table[side_num][0] - 1); get_nodes(exoid, side_set_node_list, node_pos + 1, connect, connect_offset + tri3_table[side_num][1] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 2); /* 2 node object */ if (side_num + 1 <= 2) /* 3, 4, 6, 7-node face */ { if (num_nodes_per_elem == 3) /* 3-node face */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node object */ get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + tri3_table[side_num][2] - 1); } else if (num_nodes_per_elem == 4) /* 4-node face */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 4); /* 4 node object */ get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + tri3_table[side_num][2] - 1); get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + 4 - 1); /* Center node of 4-noded face */ } else if (num_nodes_per_elem == 6) /* 6-node face */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 6); /* 6 node object */ get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + tri3_table[side_num][2] - 1); get_nodes(exoid, side_set_node_list, node_pos + 3, connect, connect_offset + tri3_table[side_num][3] - 1); get_nodes(exoid, side_set_node_list, node_pos + 4, connect, connect_offset + tri3_table[side_num][4] - 1); get_nodes(exoid, side_set_node_list, node_pos + 5, connect, connect_offset + tri3_table[side_num][5] - 1); } else if (num_nodes_per_elem == 7) /* 7-node face */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 7); /* 7 node object */ get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + tri3_table[side_num][2] - 1); get_nodes(exoid, side_set_node_list, node_pos + 3, connect, connect_offset + tri3_table[side_num][3] - 1); get_nodes(exoid, side_set_node_list, node_pos + 4, connect, connect_offset + tri3_table[side_num][4] - 1); get_nodes(exoid, side_set_node_list, node_pos + 5, connect, connect_offset + tri3_table[side_num][5] - 1); get_nodes(exoid, side_set_node_list, node_pos + 6, connect, connect_offset + tri3_table[side_num][6] - 1); } else { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: %d is an unsupported number of nodes for the triangle element type", (int)num_nodes_per_elem); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } } else /* 2- or 3-node edge */ { if (num_nodes_per_elem > 3) /* 3-node edge */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node object */ get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + tri3_table[side_num][2] - 1); } } } break; } case EX_EL_QUAD: { if (check_valid_side(side_num, 4, "quad", exoid) != EX_NOERR) { goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos + 0, connect, connect_offset + quad_table[side_num][0] - 1); get_nodes(exoid, side_set_node_list, node_pos + 1, connect, connect_offset + quad_table[side_num][1] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 2); /* 2 node object */ if (num_nodes_per_elem > 5) { set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node object */ get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + quad_table[side_num][2] - 1); } break; } case EX_EL_SHELL: { if (check_valid_side(side_num, 6, "shell", exoid) != EX_NOERR) { goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos + 0, connect, connect_offset + shell_table[side_num][0] - 1); get_nodes(exoid, side_set_node_list, node_pos + 1, connect, connect_offset + shell_table[side_num][1] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 2); /* 2 node object */ if (num_nodes_per_elem > 2) { /*** KLUGE for 2D shells ***/ if (side_num + 1 <= 2) { /* 4-node face */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 4); /* 4 node object */ get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + shell_table[side_num][2] - 1); get_nodes(exoid, side_set_node_list, node_pos + 3, connect, connect_offset + shell_table[side_num][3] - 1); } } if (num_nodes_per_elem == 8) { if (side_num + 1 <= 2) { /* 8-node face */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 8); /* 8 node object */ get_nodes(exoid, side_set_node_list, node_pos + 4, connect, connect_offset + shell_table[side_num][4] - 1); get_nodes(exoid, side_set_node_list, node_pos + 5, connect, connect_offset + shell_table[side_num][5] - 1); get_nodes(exoid, side_set_node_list, node_pos + 6, connect, connect_offset + shell_table[side_num][6] - 1); get_nodes(exoid, side_set_node_list, node_pos + 7, connect, connect_offset + shell_table[side_num][7] - 1); } else { set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node edge */ get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + shell_table[side_num][2] - 1); } } if (num_nodes_per_elem == 9) { if (side_num + 1 <= 2) { /* 9-node face */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 9); /* 9 node object */ get_nodes(exoid, side_set_node_list, node_pos + 4, connect, connect_offset + shell_table[side_num][4] - 1); get_nodes(exoid, side_set_node_list, node_pos + 5, connect, connect_offset + shell_table[side_num][5] - 1); get_nodes(exoid, side_set_node_list, node_pos + 6, connect, connect_offset + shell_table[side_num][6] - 1); get_nodes(exoid, side_set_node_list, node_pos + 7, connect, connect_offset + shell_table[side_num][7] - 1); get_nodes(exoid, side_set_node_list, node_pos + 8, connect, connect_offset + shell_table[side_num][8] - 1); } else { set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node edge */ get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + shell_table[side_num][2] - 1); } } break; } case EX_EL_TETRA: { if (check_valid_side(side_num, 4, "tetra", exoid) != EX_NOERR) { goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos + 0, connect, connect_offset + tetra_table[side_num][0] - 1); get_nodes(exoid, side_set_node_list, node_pos + 1, connect, connect_offset + tetra_table[side_num][1] - 1); get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + tetra_table[side_num][2] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node object */ if (num_nodes_per_elem == 8) { set_count(exoid, side_set_node_cnt_list, elem_ndx, 4); /* 4 node object */ get_nodes(exoid, side_set_node_list, node_pos + 3, connect, connect_offset + tetra_table[side_num][3] - 1); } else if (num_nodes_per_elem > 8) { set_count(exoid, side_set_node_cnt_list, elem_ndx, 6); /* 6 node object */ get_nodes(exoid, side_set_node_list, node_pos + 3, connect, connect_offset + tetra_table[side_num][3] - 1); get_nodes(exoid, side_set_node_list, node_pos + 4, connect, connect_offset + tetra_table[side_num][4] - 1); get_nodes(exoid, side_set_node_list, node_pos + 5, connect, connect_offset + tetra_table[side_num][5] - 1); } break; } case EX_EL_WEDGE: { int node_off = 0; if (check_valid_side(side_num, 5, "wedge", exoid) != EX_NOERR) { goto cleanup; } if (num_nodes_per_elem == 6 || num_nodes_per_elem == 7) { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge6_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge6_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge6_table[side_num][node_off++] - 1); if (side_num == 3 || side_num == 4) { /* This is one of the triangular faces */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node side */ assert(node_off == 3); } else { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge6_table[side_num][node_off++] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 4); /* 4 node side */ assert(node_off == 4); } } else if (num_nodes_per_elem == 15 || num_nodes_per_elem == 16) { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge15_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge15_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge15_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge15_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge15_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge15_table[side_num][node_off++] - 1); if (side_num == 3 || side_num == 4) { /* This is one of the triangular faces */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 6); /* 6 node side */ assert(node_off == 6); } else { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge15_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge15_table[side_num][node_off++] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 8); /* 8 node side */ assert(node_off == 8); } } else if (num_nodes_per_elem == 20) { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge20_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge20_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge20_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge20_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge20_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge20_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge20_table[side_num][node_off++] - 1); if (side_num == 3 || side_num == 4) { /* This is one of the triangular faces */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 7); /* 7 node side */ assert(node_off == 7); } else { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge20_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge20_table[side_num][node_off++] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 9); /* 9 node side */ assert(node_off == 9); } } else if (num_nodes_per_elem == 21) { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge21_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge21_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge21_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge21_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge21_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge21_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge21_table[side_num][node_off++] - 1); if (side_num == 3 || side_num == 4) { /* This is one of the triangular faces */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 7); /* 7 node side */ } else { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge21_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge21_table[side_num][node_off++] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 9); /* 9 node side */ } } else if (num_nodes_per_elem == 18) { /* Wedge 18 - 9-node quad faces (0,1,2) and 6-node tri faces (3,4) */ /* All faces (quad or tri) have at least 6 nodes */ /* This gets nodes 1-6 */ get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge18_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge18_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge18_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge18_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge18_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge18_table[side_num][node_off++] - 1); if (side_num == 3 || side_num == 4) { set_count(exoid, side_set_node_cnt_list, elem_ndx, 6); /* 6 node side */ assert(node_off == 6); } else { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge18_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge18_table[side_num][node_off++] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + wedge18_table[side_num][node_off++] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 9); /* 9 node side */ assert(node_off == 9); } } break; } case EX_EL_PYRAMID: { /* * node count: 5 -- 4-node quad, 3-node tri * 13 8 6 * 14 9 6 * 18 9 7 * 19 9 7 + volume center node. */ if (check_valid_side(side_num, 5, "pyramid", exoid) != EX_NOERR) { goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + pyramid_table[side_num][0] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + pyramid_table[side_num][1] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + pyramid_table[side_num][2] - 1); if (pyramid_table[side_num][3] == 0) { /* degenerate side? */ set_count(exoid, side_set_node_cnt_list, elem_ndx, 3); /* 3 node side */ } else { get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + pyramid_table[side_num][3] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 4); /* 4 node side */ } if (num_nodes_per_elem > 5) { /* This gets the mid-edge nodes for three edges */ get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + pyramid_table[side_num][4] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + pyramid_table[side_num][5] - 1); get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + pyramid_table[side_num][6] - 1); if (side_num == 4) { int face_node_count = num_nodes_per_elem >= 14 ? 9 : 8; set_count(exoid, side_set_node_cnt_list, elem_ndx, face_node_count); /* Get the last mid-edge node if this is quad face topology */ get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + pyramid_table[side_num][7] - 1); if (num_nodes_per_elem >= 14) { /* Get the mid-face node for the quad */ get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + pyramid_table[side_num][8] - 1); } } else { /* Triangular faces... */ int face_node_count = num_nodes_per_elem >= 18 ? 7 : 6; set_count(exoid, side_set_node_cnt_list, elem_ndx, face_node_count); if (num_nodes_per_elem >= 18) { /* Get the mid-face node for the tri */ get_nodes(exoid, side_set_node_list, node_pos++, connect, connect_offset + pyramid_table[side_num][8] - 1); } } } break; } case EX_EL_HEX: { if (check_valid_side(side_num, 6, "hex", exoid) != EX_NOERR) { goto cleanup; } get_nodes(exoid, side_set_node_list, node_pos + 0, connect, connect_offset + hex_table[side_num][0] - 1); get_nodes(exoid, side_set_node_list, node_pos + 1, connect, connect_offset + hex_table[side_num][1] - 1); get_nodes(exoid, side_set_node_list, node_pos + 2, connect, connect_offset + hex_table[side_num][2] - 1); get_nodes(exoid, side_set_node_list, node_pos + 3, connect, connect_offset + hex_table[side_num][3] - 1); set_count(exoid, side_set_node_cnt_list, elem_ndx, 4); /* 4 node object */ if (num_nodes_per_elem > 12) /* more nodes than HEXSHELL */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 8); /* 8 node object */ get_nodes(exoid, side_set_node_list, node_pos + 4, connect, connect_offset + hex_table[side_num][4] - 1); get_nodes(exoid, side_set_node_list, node_pos + 5, connect, connect_offset + hex_table[side_num][5] - 1); get_nodes(exoid, side_set_node_list, node_pos + 6, connect, connect_offset + hex_table[side_num][6] - 1); get_nodes(exoid, side_set_node_list, node_pos + 7, connect, connect_offset + hex_table[side_num][7] - 1); } if (num_nodes_per_elem == 27) /* 27-node brick */ { set_count(exoid, side_set_node_cnt_list, elem_ndx, 9); /* 9 node object */ get_nodes(exoid, side_set_node_list, node_pos + 8, connect, connect_offset + hex_table[side_num][8] - 1); } break; } default: { exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: %s is an unsupported element type", elem_blk_parms[parm_ndx].elem_type); ex_err("ex_get_side_set_node_list", errmsg, exerrval); err_stat = EX_FATAL; goto cleanup; } } } /* All done: release connectivity array space, element block ids array, element block parameters array, and side set element index array */ cleanup: free(connect); free(ss_parm_ndx); free(elem_blk_ids); free(elem_blk_parms); free(ss_elem_ndx); free(ss_elem_node_ndx); free(side_set_side_list); free(side_set_elem_list); return (err_stat); }
int ex_get_side_set_node_list_len(int exoid, ex_entity_id side_set_id, void_int *side_set_node_list_len) { size_t i, j; size_t m; int64_t num_side_sets, num_elem_blks, num_df, ndim; size_t list_len = 0; int64_t tot_num_elem = 0, tot_num_ss_elem = 0; void_int *elem_blk_ids; int *ss_elem_ndx = NULL; int64_t *ss_elem_ndx_64 = NULL; void_int *side_set_elem_list; void_int *side_set_side_list; int elem_ctr; int status; struct elem_blk_parm *elem_blk_parms; char errmsg[MAX_ERR_LENGTH]; exerrval = 0; /* clear error code */ if (ex_int64_status(exoid) & EX_BULK_INT64_API) *(int64_t*)side_set_node_list_len = 0; /* default value */ else *(int*)side_set_node_list_len = 0; /* default value */ /* first check if any side sets are specified */ /* inquire how many side sets have been stored */ /* get the dimensionality of the coordinates; this is necessary to distinguish between 2d TRIs and 3d TRIs */ ndim = ex_inquire_int(exoid, EX_INQ_DIM); if (ndim < 0) { sprintf(errmsg, "Error: failed to get dimensionality in file id %d",exoid); ex_err("ex_get_side_set_node_list_len",errmsg,exerrval); return(EX_FATAL); } tot_num_elem = ex_inquire_int(exoid, EX_INQ_ELEM); if (tot_num_elem < 0) { sprintf(errmsg, "Error: failed to get total number of elements in file id %d",exoid); ex_err("ex_get_side_set_node_list_len",errmsg,exerrval); return(EX_FATAL); } num_elem_blks = ex_inquire_int(exoid, EX_INQ_ELEM_BLK); if (num_elem_blks < 0) { sprintf(errmsg, "Error: failed to get number of element blocks in file id %d",exoid); ex_err("ex_get_side_set_node_list_len",errmsg,exerrval); return(EX_FATAL); } num_side_sets = ex_inquire_int(exoid, EX_INQ_SIDE_SETS); if (num_side_sets < 0) { sprintf(errmsg, "Error: failed to get number of side sets in file id %d",exoid); ex_err("ex_get_side_set_node_list_len",errmsg,exerrval); return(EX_FATAL); } if (num_side_sets == 0) { sprintf(errmsg, "Warning: no side sets defined in file id %d",exoid); ex_err("ex_get_side_set_node_list_len",errmsg,EX_WARN); return(EX_WARN); } /* First determine the # of elements in the side set*/ if (ex_int64_status(exoid) & EX_BULK_INT64_API) { status = ex_get_side_set_param(exoid,side_set_id,&tot_num_ss_elem,&num_df); } else { int tot; int df; status = ex_get_side_set_param(exoid,side_set_id,&tot,&df); tot_num_ss_elem = tot; num_df = df; } if (status != NC_NOERR) { sprintf(errmsg, "Error: failed to get number of elements in side set %"PRId64" in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_list_len",errmsg,exerrval); return(EX_FATAL); } if (tot_num_ss_elem == 0) /* NULL side set? */ return (EX_NOERR); /* return zero */ /* Minor optimization/kluge -- If num_df is nonzero, or 1 per face then assume that it matches the number of nodes in the sideset... */ if (num_df > 0 && num_df != tot_num_ss_elem) { if (ex_int64_status(exoid) & EX_BULK_INT64_API) *(int64_t*)side_set_node_list_len = num_df; else *(int*)side_set_node_list_len = num_df; return(EX_NOERR); } /* Allocate space for the side set element list */ { int int_size = sizeof(int); if (ex_int64_status(exoid) & EX_BULK_INT64_API) int_size = sizeof(int64_t); if (!(side_set_elem_list=malloc(tot_num_ss_elem*int_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set element list for file id %d", exoid); ex_err("ex_get_side_set_node_list_len",errmsg,exerrval); return (EX_FATAL); } /* Allocate space for the side set side list */ if (!(side_set_side_list=malloc(tot_num_ss_elem*int_size))) { safe_free(side_set_elem_list); exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set side list for file id %d", exoid); ex_err("ex_get_side_set_node_list_len",errmsg,exerrval); return (EX_FATAL); } if (ex_get_side_set(exoid, side_set_id, side_set_elem_list, side_set_side_list) != NC_NOERR) { safe_free(side_set_elem_list); safe_free(side_set_side_list); sprintf(errmsg, "Error: failed to get side set %"PRId64" in file id %d", side_set_id, exoid); ex_err("ex_get_side_set_node_list_len",errmsg,exerrval); return (EX_FATAL); } /* Allocate space for the ss element index array */ if (int_size == sizeof(int64_t)) { ss_elem_ndx_64=malloc(tot_num_ss_elem*int_size); } else { ss_elem_ndx =malloc(tot_num_ss_elem*int_size); } if (ss_elem_ndx_64==NULL && ss_elem_ndx == NULL) { safe_free(side_set_elem_list); safe_free(side_set_side_list); exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set elem sort array for file id %d", exoid); ex_err("ex_get_side_set_node_list_len",errmsg,exerrval); return (EX_FATAL); } } /* Sort side set element list into index array - non-destructive */ if (ex_int64_status(exoid) & EX_BULK_INT64_API) { for (i=0;i<tot_num_ss_elem;i++) ss_elem_ndx_64[i] = i; /* init index array to current position */ ex_iqsort64(side_set_elem_list, ss_elem_ndx_64,tot_num_ss_elem); } else { for (i=0;i<tot_num_ss_elem;i++) ss_elem_ndx[i] = i; /* init index array to current position */ ex_iqsort(side_set_elem_list, ss_elem_ndx,tot_num_ss_elem); } /* Allocate space for the element block ids */ { int int_size = sizeof(int); if (ex_int64_status(exoid) & EX_IDS_INT64_API) { int_size = sizeof(int64_t); } if (!(elem_blk_ids=malloc(num_elem_blks*int_size))) { exerrval = EX_MEMFAIL; safe_free(ss_elem_ndx); safe_free(ss_elem_ndx_64); safe_free(side_set_side_list); safe_free(side_set_elem_list); sprintf(errmsg, "Error: failed to allocate space for element block ids for file id %d", exoid); ex_err("ex_get_side_set_node_list_len",errmsg,exerrval); return (EX_FATAL); } } if (ex_get_elem_blk_ids(exoid, elem_blk_ids)) { safe_free(elem_blk_ids); safe_free(ss_elem_ndx); safe_free(ss_elem_ndx_64); safe_free(side_set_side_list); safe_free(side_set_elem_list); sprintf(errmsg, "Error: failed to get element block ids in file id %d", exoid); ex_err("ex_get_side_set_node_list_len",errmsg,EX_MSG); return(EX_FATAL); } /* Allocate space for the element block params */ if (!(elem_blk_parms=malloc(num_elem_blks*sizeof(struct elem_blk_parm)))) { safe_free(elem_blk_ids); safe_free(ss_elem_ndx); safe_free(ss_elem_ndx_64); safe_free(side_set_side_list); safe_free(side_set_elem_list); exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for element block params for file id %d", exoid); ex_err("ex_get_side_set_node_list_len",errmsg,exerrval); return (EX_FATAL); } elem_ctr = 0; for (i=0; i<num_elem_blks; i++) { ex_block block; block.type = EX_ELEM_BLOCK; if (ex_int64_status(exoid) & EX_IDS_INT64_API) { block.id = ((int64_t*)elem_blk_ids)[i]; } else { block.id = ((int*)elem_blk_ids)[i]; } /* read in an element block parameter */ if ((ex_get_block_param (exoid, &block)) != NC_NOERR) { safe_free(elem_blk_parms); safe_free(elem_blk_ids); safe_free(ss_elem_ndx); safe_free(ss_elem_ndx_64); safe_free(side_set_side_list); safe_free(side_set_elem_list); sprintf(errmsg, "Error: failed to get element block %"PRId64" parameters in file id %d", block.id, exoid); ex_err("ex_get_side_set_node_list_len",errmsg,EX_MSG); return(EX_FATAL); } elem_blk_parms[i].num_elem_in_blk = block.num_entry; elem_blk_parms[i].num_nodes_per_elem = block.num_nodes_per_entry; elem_blk_parms[i].num_attr = block.num_attribute; elem_blk_parms[i].elem_blk_id = block.id; for (m=0; m < strlen(block.topology); m++) { elem_blk_parms[i].elem_type[m] = toupper(block.topology[m]); } elem_blk_parms[i].elem_type[m] = '\0'; if (strncmp(elem_blk_parms[i].elem_type,"CIRCLE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_CIRCLE; /* set side set node stride */ elem_blk_parms[i].num_nodes_per_side[0] = 1; } else if (strncmp(elem_blk_parms[i].elem_type,"SPHERE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_SPHERE; /* set side set node stride */ elem_blk_parms[i].num_nodes_per_side[0] = 1; } else if (strncmp(elem_blk_parms[i].elem_type,"QUAD",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_QUAD; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 4) elem_blk_parms[i].num_nodes_per_side[0] = 2; else if (elem_blk_parms[i].num_nodes_per_elem == 5) elem_blk_parms[i].num_nodes_per_side[0] = 2; else elem_blk_parms[i].num_nodes_per_side[0] = 3; } else if (strncmp(elem_blk_parms[i].elem_type,"TRIANGLE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_TRIANGLE; /* determine side set node stride */ if (ndim == 2) /* 2d TRIs */ { if (elem_blk_parms[i].num_nodes_per_elem == 3) elem_blk_parms[i].num_nodes_per_side[0] = 2; else elem_blk_parms[i].num_nodes_per_side[0] = 3; } else if (ndim == 3) /* 3d TRIs */ { /* set the default number of nodes per side; catch exceptions later */ if (elem_blk_parms[i].num_nodes_per_elem == 3) elem_blk_parms[i].num_nodes_per_side[0] = 3; else elem_blk_parms[i].num_nodes_per_side[0] = 6; } } else if (strncmp(elem_blk_parms[i].elem_type,"SHELL",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_SHELL; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 2) /* KLUDGE for 2D Shells*/ elem_blk_parms[i].num_nodes_per_side[0] = 2; else if (elem_blk_parms[i].num_nodes_per_elem == 4) elem_blk_parms[i].num_nodes_per_side[0] = 4; else elem_blk_parms[i].num_nodes_per_side[0] = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"HEX",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_HEX; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 8) elem_blk_parms[i].num_nodes_per_side[0] = 4; else if (elem_blk_parms[i].num_nodes_per_elem == 9) elem_blk_parms[i].num_nodes_per_side[0] = 4; else if (elem_blk_parms[i].num_nodes_per_elem == 12) /* HEXSHELL */ elem_blk_parms[i].num_nodes_per_side[0] = 4; else if (elem_blk_parms[i].num_nodes_per_elem == 27) elem_blk_parms[i].num_nodes_per_side[0] = 9; else elem_blk_parms[i].num_nodes_per_side[0] = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"TETRA",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_TETRA; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 4) elem_blk_parms[i].num_nodes_per_side[0] = 3; else if (elem_blk_parms[i].num_nodes_per_elem == 8) elem_blk_parms[i].num_nodes_per_side[0] = 4; else elem_blk_parms[i].num_nodes_per_side[0] = 6; } else if (strncmp(elem_blk_parms[i].elem_type,"WEDGE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_WEDGE; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 6) elem_blk_parms[i].num_nodes_per_side[0] = 4; else elem_blk_parms[i].num_nodes_per_side[0] = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"PYRAMID",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_PYRAMID; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 5) elem_blk_parms[i].num_nodes_per_side[0] = 4; else elem_blk_parms[i].num_nodes_per_side[0] = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"BEAM",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_BEAM; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 2) elem_blk_parms[i].num_nodes_per_side[0] = 2; else elem_blk_parms[i].num_nodes_per_side[0] = 3; } else if ( (strncmp(elem_blk_parms[i].elem_type,"TRUSS",3) == 0) || (strncmp(elem_blk_parms[i].elem_type,"BAR",3) == 0) || (strncmp(elem_blk_parms[i].elem_type,"EDGE",3) == 0)) { elem_blk_parms[i].elem_type_val = EX_EL_TRUSS; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 2) elem_blk_parms[i].num_nodes_per_side[0] = 2; else elem_blk_parms[i].num_nodes_per_side[0] = 3; } else if (strncmp(elem_blk_parms[i].elem_type,"NULL",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_NULL_ELEMENT; elem_blk_parms[i].num_nodes_per_side[0] = 0; elem_blk_parms[i].num_elem_in_blk = 0; } else { /* unsupported element type; no problem if no sides specified for this element block */ elem_blk_parms[i].elem_type_val = EX_EL_UNK; elem_blk_parms[i].num_nodes_per_side[0] = 0; } elem_ctr += elem_blk_parms[i].num_elem_in_blk; elem_blk_parms[i].elem_ctr = elem_ctr; /* save elem number max */ } /* Walk through element list and keep a running count of the node length */ list_len = 0; for (i=0;i<tot_num_ss_elem;i++) { size_t elem; size_t side; if (ex_int64_status(exoid) & EX_BULK_INT64_API) { elem = ((int64_t*)side_set_elem_list)[i]; side = ((int64_t*)side_set_side_list)[i]; } else { elem = ((int*)side_set_elem_list)[i]; side = ((int*)side_set_side_list)[i]; } for (j=0; j<num_elem_blks; j++) { if (elem_blk_parms[j].elem_type_val != EX_EL_NULL_ELEMENT) if (elem <= elem_blk_parms[j].elem_ctr) break; /* stop because we found the parameters for this element */ } if (j >= num_elem_blks) { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid element number %"ST_ZU" found in side set %"PRId64" in file %d", elem, side_set_id, exoid); safe_free(elem_blk_parms); safe_free(elem_blk_ids); safe_free(ss_elem_ndx); safe_free(ss_elem_ndx_64); safe_free(side_set_side_list); safe_free(side_set_elem_list); ex_err("ex_get_side_set_node_list_len",errmsg,EX_MSG); return (EX_FATAL); } /* Update *side_set_node_list_len (which points to next node in chain */ /* WEDGEs with 3 node sides (side 4 or 5) are special cases */ if (elem_blk_parms[j].elem_type_val == EX_EL_WEDGE && (side == 4 || side == 5)) { if (elem_blk_parms[j].num_nodes_per_elem == 6) list_len += 3; /* 3 node side */ else list_len += 6; /* 6 node side */ } /* PYRAMIDSs with 3 node sides (sides 1,2,3,4) are also special */ else if (elem_blk_parms[j].elem_type_val == EX_EL_PYRAMID && (side < 5)) { if (elem_blk_parms[j].num_nodes_per_elem == 5) list_len += 3; /* 3 node side */ else list_len += 6; /* 6 node side */ } /* side numbers 3,4,5,6 for SHELLs are also special */ else if (elem_blk_parms[j].elem_type_val == EX_EL_SHELL && (side > 2 )) { if (elem_blk_parms[j].num_nodes_per_elem == 4) list_len += 2; /* 2 node side */ else list_len += 3; /* 3 node side */ } /* sides 3, 4, and 5 of 3d TRIs are special cases */ else if (elem_blk_parms[j].elem_type_val == EX_EL_TRIANGLE && ndim == 3 && side > 2 ) { if (elem_blk_parms[j].num_nodes_per_elem == 3) /* 3-node TRI */ list_len += 2; /* 2 node side */ else /* 6-node TRI */ list_len += 3; /* 3 node side */ } else if (elem_blk_parms[j].elem_type_val == EX_EL_UNK) { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: %s in elem block %"PRId64" is an unsupported element type", elem_blk_parms[i].elem_type, elem_blk_parms[i].elem_blk_id); safe_free(elem_blk_parms); safe_free(elem_blk_ids); safe_free(ss_elem_ndx); safe_free(ss_elem_ndx_64); safe_free(side_set_side_list); safe_free(side_set_elem_list); ex_err("ex_get_side_set_node_list_len",errmsg,EX_MSG); return (EX_FATAL); } else /* all other element types */ list_len += elem_blk_parms[j].num_nodes_per_side[0]; } if (ex_int64_status(exoid) & EX_BULK_INT64_API) *(int64_t*)side_set_node_list_len = list_len; else *(int*)side_set_node_list_len = list_len; /* All done: release element block ids array, element block parameters array, and side set element index array */ safe_free(elem_blk_ids); safe_free(elem_blk_parms); safe_free(ss_elem_ndx); safe_free(ss_elem_ndx_64); safe_free(side_set_side_list); safe_free(side_set_elem_list); return(EX_NOERR); }
/*! \undoc */ int ex_get_concat_side_set_node_count(int exoid, int *side_set_node_cnt_list) { size_t m; int ii, i, j, iss, ioff; ex_entity_id side_set_id; int num_side_sets, num_elem_blks, num_df, ndim; int64_t tot_num_elem = 0, tot_num_ss_elem = 0, side, elem; void_int *elem_blk_ids = NULL; void_int *side_set_ids = NULL; void_int *ss_elem_ndx = NULL; void_int *side_set_elem_list = NULL; void_int *side_set_side_list = NULL; size_t elem_ctr; int int_size, ids_size; int status; struct elem_blk_parm *elem_blk_parms; char errmsg[MAX_ERR_LENGTH]; exerrval = 0; /* clear error code */ /* first check if any side sets are specified */ /* inquire how many side sets have been stored */ num_side_sets = ex_inquire_int(exoid, EX_INQ_SIDE_SETS); if (num_side_sets < 0) { sprintf(errmsg, "Error: failed to get number of side sets in file id %d",exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,exerrval); return(EX_FATAL); } if (num_side_sets == 0) { sprintf(errmsg, "Warning: no side sets defined in file id %d",exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,EX_WARN); return(EX_WARN); } num_elem_blks = ex_inquire_int(exoid, EX_INQ_ELEM_BLK); if (num_elem_blks < 0) { sprintf(errmsg, "Error: failed to get number of element blocks in file id %d",exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,exerrval); return(EX_FATAL); } tot_num_elem = ex_inquire_int(exoid, EX_INQ_ELEM); if (tot_num_elem < 0) { sprintf(errmsg, "Error: failed to get total number of elements in file id %d",exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,exerrval); return(EX_FATAL); } /* get the dimensionality of the coordinates; this is necessary to distinguish between 2d TRIs and 3d TRIs */ ndim = ex_inquire_int(exoid, EX_INQ_DIM); if (ndim < 0) { sprintf(errmsg, "Error: failed to get dimensionality in file id %d",exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); return(EX_FATAL); } int_size = sizeof(int); if (ex_int64_status(exoid) & EX_BULK_INT64_API) int_size = sizeof(int64_t); /* Allocate space for the element block ids */ ids_size = sizeof(int); if (ex_int64_status(exoid) & EX_IDS_INT64_API) { ids_size = sizeof(int64_t); } if (!(elem_blk_ids=malloc(num_elem_blks*ids_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for element block ids for file id %d", exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,exerrval); goto error_ret; } if (ex_get_ids(exoid, EX_ELEM_BLOCK, elem_blk_ids) == -1) { sprintf(errmsg, "Error: failed to get element block ids in file id %d", exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,EX_MSG); return(EX_FATAL); } /* Allocate space for the element block params */ if (!(elem_blk_parms=malloc(num_elem_blks*sizeof(struct elem_blk_parm)))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for element block params for file id %d", exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,exerrval); goto error_ret; } elem_ctr = 0; for (i=0; i<num_elem_blks; i++) { ex_entity_id id; ex_block block; if (ex_int64_status(exoid) & EX_IDS_INT64_API) { id = ((int64_t*)elem_blk_ids)[i]; } else { id = ((int*)elem_blk_ids)[i]; } /* read in an element block parameter */ block.type = EX_ELEM_BLOCK; block.id = id; /* read in an element block parameter */ if ((ex_get_block_param (exoid, &block)) == -1) { sprintf(errmsg, "Error: failed to get element block %"PRId64" parameters in file id %d", block.id, exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,EX_MSG); return(EX_FATAL); } elem_blk_parms[i].num_elem_in_blk = block.num_entry; elem_blk_parms[i].num_nodes_per_elem = block.num_nodes_per_entry; elem_blk_parms[i].num_attr = block.num_attribute; for (m=0; m < strlen(block.topology); m++) { elem_blk_parms[i].elem_type[m] = toupper(block.topology[m]); } elem_blk_parms[i].elem_type[m] = '\0'; if (strncmp(elem_blk_parms[i].elem_type,"CIRCLE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_CIRCLE; elem_blk_parms[i].num_sides = 1; elem_blk_parms[i].num_nodes_per_side[0] = 1; } else if (strncmp(elem_blk_parms[i].elem_type,"SPHERE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_SPHERE; elem_blk_parms[i].num_sides = 1; elem_blk_parms[i].num_nodes_per_side[0] = 1; } else if (strncmp(elem_blk_parms[i].elem_type,"QUAD",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_QUAD; elem_blk_parms[i].num_sides = 4; if (elem_blk_parms[i].num_nodes_per_elem == 4) { elem_blk_parms[i].num_nodes_per_side[0] = 2; elem_blk_parms[i].num_nodes_per_side[1] = 2; elem_blk_parms[i].num_nodes_per_side[2] = 2; elem_blk_parms[i].num_nodes_per_side[3] = 2; } else if (elem_blk_parms[i].num_nodes_per_elem == 5) { elem_blk_parms[i].num_nodes_per_side[0] = 2; elem_blk_parms[i].num_nodes_per_side[1] = 2; elem_blk_parms[i].num_nodes_per_side[2] = 2; elem_blk_parms[i].num_nodes_per_side[3] = 2; } else if (elem_blk_parms[i].num_nodes_per_elem == 9 || elem_blk_parms[i].num_nodes_per_elem == 8) { elem_blk_parms[i].num_nodes_per_side[0] = 3; elem_blk_parms[i].num_nodes_per_side[1] = 3; elem_blk_parms[i].num_nodes_per_side[2] = 3; elem_blk_parms[i].num_nodes_per_side[3] = 3; } else { EL_NODE_COUNT_ERROR; } } else if (strncmp(elem_blk_parms[i].elem_type,"TRIANGLE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_TRIANGLE; if (ndim == 2) { /* 2d TRIs */ elem_blk_parms[i].num_sides = 3; if (elem_blk_parms[i].num_nodes_per_elem == 3) { elem_blk_parms[i].num_nodes_per_side[0] = 2; elem_blk_parms[i].num_nodes_per_side[1] = 2; elem_blk_parms[i].num_nodes_per_side[2] = 2; } else if (elem_blk_parms[i].num_nodes_per_elem == 6) { elem_blk_parms[i].num_nodes_per_side[0] = 3; elem_blk_parms[i].num_nodes_per_side[1] = 3; elem_blk_parms[i].num_nodes_per_side[2] = 3; } } else if (ndim == 3) { /* 3d TRIs -- triangular shell*/ elem_blk_parms[i].num_sides = 5; /* 2 Faces and 3 Edges */ if (elem_blk_parms[i].num_nodes_per_elem == 3) { elem_blk_parms[i].num_nodes_per_side[0] = 3; elem_blk_parms[i].num_nodes_per_side[1] = 3; elem_blk_parms[i].num_nodes_per_side[2] = 2; elem_blk_parms[i].num_nodes_per_side[3] = 2; elem_blk_parms[i].num_nodes_per_side[4] = 2; } else if (elem_blk_parms[i].num_nodes_per_elem == 6) { elem_blk_parms[i].num_nodes_per_side[0] = 6; elem_blk_parms[i].num_nodes_per_side[1] = 6; elem_blk_parms[i].num_nodes_per_side[2] = 3; elem_blk_parms[i].num_nodes_per_side[3] = 3; elem_blk_parms[i].num_nodes_per_side[4] = 3; } else { EL_NODE_COUNT_ERROR; } } } else if (strncmp(elem_blk_parms[i].elem_type,"SHELL",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_SHELL; if (elem_blk_parms[i].num_nodes_per_elem == 2) {/* KLUDGE for 2D Shells*/ elem_blk_parms[i].num_sides = 2; elem_blk_parms[i].num_nodes_per_side[0] = 2; elem_blk_parms[i].num_nodes_per_side[1] = 2; } else if (elem_blk_parms[i].num_nodes_per_elem == 4) { elem_blk_parms[i].num_sides = 6; /* 2 Faces, 4 Edges */ elem_blk_parms[i].num_nodes_per_side[0] = 4; elem_blk_parms[i].num_nodes_per_side[1] = 4; elem_blk_parms[i].num_nodes_per_side[2] = 2; elem_blk_parms[i].num_nodes_per_side[3] = 2; elem_blk_parms[i].num_nodes_per_side[4] = 2; elem_blk_parms[i].num_nodes_per_side[5] = 2; } else if (elem_blk_parms[i].num_nodes_per_elem == 8 || elem_blk_parms[i].num_nodes_per_elem == 9) { elem_blk_parms[i].num_sides = 6; /* 2 Faces, 4 Edges */ elem_blk_parms[i].num_nodes_per_side[0] = elem_blk_parms[i].num_nodes_per_elem; /* 8 or 9 */ elem_blk_parms[i].num_nodes_per_side[1] = elem_blk_parms[i].num_nodes_per_elem; /* 8 or 9 */ elem_blk_parms[i].num_nodes_per_side[2] = 3; elem_blk_parms[i].num_nodes_per_side[3] = 3; elem_blk_parms[i].num_nodes_per_side[4] = 3; elem_blk_parms[i].num_nodes_per_side[5] = 3; } else { EL_NODE_COUNT_ERROR; } } else if (strncmp(elem_blk_parms[i].elem_type,"HEX",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_HEX; elem_blk_parms[i].num_sides = 6; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 8) { /* 8-node bricks */ elem_blk_parms[i].num_nodes_per_side[0] = 4; elem_blk_parms[i].num_nodes_per_side[1] = 4; elem_blk_parms[i].num_nodes_per_side[2] = 4; elem_blk_parms[i].num_nodes_per_side[3] = 4; elem_blk_parms[i].num_nodes_per_side[4] = 4; elem_blk_parms[i].num_nodes_per_side[5] = 4; } else if (elem_blk_parms[i].num_nodes_per_elem == 9) { /* 9-node bricks */ elem_blk_parms[i].num_nodes_per_side[0] = 4; elem_blk_parms[i].num_nodes_per_side[1] = 4; elem_blk_parms[i].num_nodes_per_side[2] = 4; elem_blk_parms[i].num_nodes_per_side[3] = 4; elem_blk_parms[i].num_nodes_per_side[4] = 4; elem_blk_parms[i].num_nodes_per_side[5] = 4; } else if (elem_blk_parms[i].num_nodes_per_elem == 12) { /* HEXSHELLS */ elem_blk_parms[i].num_nodes_per_side[0] = 6; elem_blk_parms[i].num_nodes_per_side[1] = 6; elem_blk_parms[i].num_nodes_per_side[2] = 6; elem_blk_parms[i].num_nodes_per_side[3] = 6; elem_blk_parms[i].num_nodes_per_side[4] = 4; elem_blk_parms[i].num_nodes_per_side[5] = 4; } else if (elem_blk_parms[i].num_nodes_per_elem == 20) { /* 20-node bricks */ elem_blk_parms[i].num_nodes_per_side[0] = 8; elem_blk_parms[i].num_nodes_per_side[1] = 8; elem_blk_parms[i].num_nodes_per_side[2] = 8; elem_blk_parms[i].num_nodes_per_side[3] = 8; elem_blk_parms[i].num_nodes_per_side[4] = 8; elem_blk_parms[i].num_nodes_per_side[5] = 8; } else if (elem_blk_parms[i].num_nodes_per_elem == 27) { /* 27-node bricks */ elem_blk_parms[i].num_nodes_per_side[0] = 9; elem_blk_parms[i].num_nodes_per_side[1] = 9; elem_blk_parms[i].num_nodes_per_side[2] = 9; elem_blk_parms[i].num_nodes_per_side[3] = 9; elem_blk_parms[i].num_nodes_per_side[4] = 9; elem_blk_parms[i].num_nodes_per_side[5] = 9; } else { EL_NODE_COUNT_ERROR; } } else if (strncmp(elem_blk_parms[i].elem_type,"TETRA",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_TETRA; elem_blk_parms[i].num_sides = 4; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 4) { elem_blk_parms[i].num_nodes_per_side[0] = 3; elem_blk_parms[i].num_nodes_per_side[1] = 3; elem_blk_parms[i].num_nodes_per_side[2] = 3; elem_blk_parms[i].num_nodes_per_side[3] = 3; } else if (elem_blk_parms[i].num_nodes_per_elem == 8) { elem_blk_parms[i].num_nodes_per_side[0] = 4; elem_blk_parms[i].num_nodes_per_side[1] = 4; elem_blk_parms[i].num_nodes_per_side[2] = 4; elem_blk_parms[i].num_nodes_per_side[3] = 4; } else if (elem_blk_parms[i].num_nodes_per_elem == 10) { elem_blk_parms[i].num_nodes_per_side[0] = 6; elem_blk_parms[i].num_nodes_per_side[1] = 6; elem_blk_parms[i].num_nodes_per_side[2] = 6; elem_blk_parms[i].num_nodes_per_side[3] = 6; } else { EL_NODE_COUNT_ERROR; } } else if (strncmp(elem_blk_parms[i].elem_type,"WEDGE",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_WEDGE; elem_blk_parms[i].num_sides = 5; if (elem_blk_parms[i].num_nodes_per_elem == 6) { elem_blk_parms[i].num_nodes_per_side[0] = 4; elem_blk_parms[i].num_nodes_per_side[1] = 4; elem_blk_parms[i].num_nodes_per_side[2] = 4; elem_blk_parms[i].num_nodes_per_side[3] = 3; elem_blk_parms[i].num_nodes_per_side[4] = 3; } else if (elem_blk_parms[i].num_nodes_per_elem == 15){ elem_blk_parms[i].num_nodes_per_side[0] = 8; elem_blk_parms[i].num_nodes_per_side[1] = 8; elem_blk_parms[i].num_nodes_per_side[2] = 8; elem_blk_parms[i].num_nodes_per_side[3] = 6; elem_blk_parms[i].num_nodes_per_side[4] = 6; } else { EL_NODE_COUNT_ERROR; } } else if (strncmp(elem_blk_parms[i].elem_type,"PYRAMID",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_PYRAMID; elem_blk_parms[i].num_sides = 5; if (elem_blk_parms[i].num_nodes_per_elem == 5) { elem_blk_parms[i].num_nodes_per_side[0] = 3; elem_blk_parms[i].num_nodes_per_side[1] = 3; elem_blk_parms[i].num_nodes_per_side[2] = 3; elem_blk_parms[i].num_nodes_per_side[3] = 3; elem_blk_parms[i].num_nodes_per_side[4] = 4; } else if (elem_blk_parms[i].num_nodes_per_elem == 13){ elem_blk_parms[i].num_nodes_per_side[0] = 6; elem_blk_parms[i].num_nodes_per_side[1] = 6; elem_blk_parms[i].num_nodes_per_side[2] = 6; elem_blk_parms[i].num_nodes_per_side[3] = 6; elem_blk_parms[i].num_nodes_per_side[4] = 8; } else { EL_NODE_COUNT_ERROR; } } else if (strncmp(elem_blk_parms[i].elem_type,"BEAM",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_BEAM; elem_blk_parms[i].num_sides = 2; if (elem_blk_parms[i].num_nodes_per_elem == 2) { elem_blk_parms[i].num_nodes_per_side[0] = 2; elem_blk_parms[i].num_nodes_per_side[1] = 2; } else if (elem_blk_parms[i].num_nodes_per_elem == 3){ elem_blk_parms[i].num_nodes_per_side[0] = 3; elem_blk_parms[i].num_nodes_per_side[1] = 3; } else { EL_NODE_COUNT_ERROR; } } else if ( (strncmp(elem_blk_parms[i].elem_type,"TRUSS",3) == 0) || (strncmp(elem_blk_parms[i].elem_type,"BAR",3) == 0) || (strncmp(elem_blk_parms[i].elem_type,"EDGE",3) == 0) ) { elem_blk_parms[i].elem_type_val = EX_EL_TRUSS; elem_blk_parms[i].num_sides = 2; if (elem_blk_parms[i].num_nodes_per_elem == 2) { elem_blk_parms[i].num_nodes_per_side[0] = 2; elem_blk_parms[i].num_nodes_per_side[1] = 2; } else if (elem_blk_parms[i].num_nodes_per_elem == 3) { elem_blk_parms[i].num_nodes_per_side[0] = 3; elem_blk_parms[i].num_nodes_per_side[1] = 3; } else { EL_NODE_COUNT_ERROR; } } /* Used for an empty block in a parallel decomposition */ else if (strncmp(elem_blk_parms[i].elem_type,"NULL",3) == 0) { elem_blk_parms[i].elem_type_val = EX_EL_NULL_ELEMENT; elem_blk_parms[i].num_sides = 0; elem_blk_parms[i].num_nodes_per_side[0] = 0; elem_blk_parms[i].num_elem_in_blk = 0; } else { /* unsupported element type; no problem if no sides specified for this element block */ elem_blk_parms[i].elem_type_val = EX_EL_UNK; elem_blk_parms[i].num_sides = 0; elem_blk_parms[i].num_nodes_per_side[0] = 0; } elem_blk_parms[i].elem_blk_id = id; /* save id */ elem_ctr += elem_blk_parms[i].num_elem_in_blk; elem_blk_parms[i].elem_ctr = elem_ctr; /* save elem number max */ } /* Finally... Create the list of node counts for each face in the * side set. */ /* Allocate space for the sideset ids */ if (!(side_set_ids=malloc(num_side_sets*ids_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set ids for file id %d", exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,exerrval); goto error_ret; } if (ex_get_ids(exoid, EX_SIDE_SET, side_set_ids) == -1) { sprintf(errmsg, "Error: failed to get side set ids in file id %d", exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,EX_MSG); goto error_ret; } /* Lookup index of side set id in VAR_SS_IDS array */ ioff = 0; for (iss=0; iss<num_side_sets; iss++) { if (ex_int64_status(exoid) & EX_IDS_INT64_API) { side_set_id = ((int64_t*)side_set_ids)[iss]; } else { side_set_id = ((int*)side_set_ids)[iss]; } /* First determine the # of elements in the side set*/ if (int_size == sizeof(int64_t)) { status = ex_get_set_param(exoid,EX_SIDE_SET, side_set_id,&tot_num_ss_elem,&num_df); } else { int tot, df; status = ex_get_set_param(exoid,EX_SIDE_SET, side_set_id,&tot,&df); tot_num_ss_elem = tot; num_df = df; } if (status != EX_NOERR) { sprintf(errmsg, "Error: failed to get number of elements in side set %"PRId64" in file id %d", side_set_id, exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,exerrval); goto error_ret; } if (tot_num_ss_elem == 0) continue; /* Allocate space for the side set element list */ if (!(side_set_elem_list=malloc(tot_num_ss_elem*int_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set element list for file id %d", exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,exerrval); goto error_ret; } /* Allocate space for the side set side list */ if (!(side_set_side_list=malloc(tot_num_ss_elem*int_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set side list for file id %d", exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,exerrval); goto error_ret; } if (ex_get_set(exoid, EX_SIDE_SET, side_set_id, side_set_elem_list, side_set_side_list) == -1) { sprintf(errmsg, "Error: failed to get side set %"PRId64" in file id %d", side_set_id, exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,exerrval); goto error_ret; } /* Allocate space for the ss element index array */ if (!(ss_elem_ndx=malloc(tot_num_ss_elem*int_size))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for side set elem sort array for file id %d", exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,exerrval); goto error_ret; } /* Sort side set element list into index array - non-destructive */ if (int_size == sizeof(int64_t)) { /* Sort side set element list into index array - non-destructive */ int64_t *elems = (int64_t*)ss_elem_ndx; for (i=0;i<tot_num_ss_elem;i++) { elems[i] = i; /* init index array to current position */ } ex_iqsort64(side_set_elem_list, ss_elem_ndx,tot_num_ss_elem); } else { /* Sort side set element list into index array - non-destructive */ int *elems = (int*)ss_elem_ndx; for (i=0;i<tot_num_ss_elem;i++) { elems[i] = i; /* init index array to current position */ } ex_iqsort(side_set_elem_list, ss_elem_ndx,tot_num_ss_elem); } j = 0; /* The current element block... */ for (ii=0;ii<tot_num_ss_elem;ii++) { int64_t elem_ndx; if (ex_int64_status(exoid) & EX_BULK_INT64_API) { elem_ndx = ((int64_t*)ss_elem_ndx)[ii]; elem = ((int64_t*)side_set_elem_list)[elem_ndx]; side = ((int64_t*)side_set_side_list)[elem_ndx]-1; } else { elem_ndx = ((int*)ss_elem_ndx)[ii]; elem = ((int*)side_set_elem_list)[elem_ndx]; side = ((int*)side_set_side_list)[elem_ndx]-1; } /* * Since the elements are being accessed in sorted, order, the * block that contains the elements must progress sequentially * from block 0 to block[num_elem_blks-1]. Once we find an element * not in this block, find a following block that contains it... */ for ( ; j<num_elem_blks; j++) { if (elem <= elem_blk_parms[j].elem_ctr) { break; } } if (j < num_elem_blks) { assert(side < elem_blk_parms[j].num_sides); side_set_node_cnt_list[elem_ndx+ioff] = elem_blk_parms[j].num_nodes_per_side[side]; } else { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid element number %"PRId64" found in side set %"PRId64" in file %d", elem, side_set_id, exoid); ex_err("ex_get_concat_side_set_node_count",errmsg,EX_MSG); goto error_ret; } } ss_elem_ndx = safe_free(ss_elem_ndx); side_set_elem_list = safe_free(side_set_elem_list); side_set_side_list = safe_free(side_set_side_list); ioff += tot_num_ss_elem; } /* All done: release allocated memory */ safe_free(elem_blk_ids); safe_free(side_set_ids); return(EX_NOERR); error_ret: safe_free(elem_blk_ids); safe_free(side_set_ids); safe_free(ss_elem_ndx); safe_free(side_set_elem_list); safe_free(side_set_side_list); return (EX_FATAL); }