/* read element connectivity of block with id 'block_id' */ int c_ex_get_elem_connectivity(int *exoid, int *block_id, int *elem_connectivity) { int error=0; #ifdef HAVE_LIBEXOIIV2C error = ex_get_elem_conn(*exoid, *block_id, elem_connectivity); #else FLExit("Fluidity was not configured with exodusII, reconfigure with '--with-exodusii'!"); #endif return (error); }
int ex_cvt_nodes_to_sides(int exoid, int *num_elem_per_set, int *num_nodes_per_set, int *side_sets_elem_index, int *side_sets_node_index, int *side_sets_elem_list, int *side_sets_node_list, int *side_sets_side_list) { int i, j, k, m, n; int num_side_sets, num_elem_blks; int tot_num_elem = 0, tot_num_ss_elem = 0, elem_num = 0, ndim; int *elem_blk_ids, *connect = 0; int *ss_elem_ndx, *ss_elem_node_ndx, *ss_parm_ndx; int elem_ctr, node_ctr, elem_num_pos; int num_elem_in_blk, num_nodes_per_elem, num_node_per_side, num_attr; int *same_elem_type, el_type = -1; float fdum; char *cdum, elem_type[MAX_STR_LENGTH+1]; struct elem_blk_parm *elem_blk_parms; /* 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]; (void)side_sets_elem_index; (void)side_sets_node_index; exerrval = 0; /* clear error code */ cdum = 0; /* initialize even though it is not used */ /* first check if any side sets are specified */ /* inquire how many side sets have been stored */ if ((ex_inquire(exoid, EX_INQ_SIDE_SETS, &num_side_sets, &fdum, cdum)) == -1) { sprintf(errmsg, "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) { sprintf(errmsg, "Warning: no side sets defined in file id %d",exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,EX_WARN); return(EX_WARN); } if ((ex_inquire(exoid, EX_INQ_ELEM_BLK, &num_elem_blks, &fdum, cdum)) == -1) { sprintf(errmsg, "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); } if ((ex_inquire(exoid, EX_INQ_ELEM, &tot_num_elem, &fdum, cdum)) == -1) { sprintf(errmsg, "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 */ if ((ex_inquire(exoid, EX_INQ_DIM, &ndim, &fdum, cdum)) == -1) { sprintf(errmsg, "Error: failed to get dimensionality in file id %d",exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); return(EX_FATAL); } /* First count up # of elements in the side sets*/ for (i=0;i<num_side_sets;i++) tot_num_ss_elem += num_elem_per_set[i]; /* Allocate space for the ss element index array */ if (!(ss_elem_ndx=malloc(tot_num_ss_elem*sizeof(int)))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "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); return (EX_FATAL); } /* Sort side set element list into index array - non-destructive */ for (i=0;i<tot_num_ss_elem;i++) ss_elem_ndx[i] = i; /* init index array to current position */ ex_iqsort(side_sets_elem_list, ss_elem_ndx,tot_num_ss_elem); /* Allocate space for the element block ids */ if (!(elem_blk_ids=malloc(num_elem_blks*sizeof(int)))) { free(ss_elem_ndx); exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for element block ids for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); return (EX_FATAL); } if (ex_get_elem_blk_ids(exoid, elem_blk_ids)) { free(elem_blk_ids); free(ss_elem_ndx); sprintf(errmsg, "Error: failed to get element block ids in file id %d", exoid); ex_err("ex_cvt_nodes_to_sides",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)))) { free(elem_blk_ids); free(ss_elem_ndx); exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for element block params for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); return (EX_FATAL); } elem_ctr = 0; for (i=0; i<num_elem_blks; i++) { /* read in an element block parameter */ if ((ex_get_elem_block (exoid, elem_blk_ids[i], elem_type, &num_elem_in_blk, &num_nodes_per_elem, &num_attr)) == -1) { free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); sprintf(errmsg, "Error: failed to get element block %d parameters in file id %d", elem_blk_ids[i], exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,EX_MSG); return(EX_FATAL); } elem_blk_parms[i].num_elem_in_blk = num_elem_in_blk; elem_blk_parms[i].num_nodes_per_elem = num_nodes_per_elem; elem_blk_parms[i].num_attr = num_attr; for (m=0; m < (int)strlen(elem_type); m++) elem_blk_parms[i].elem_type[m] = (char) toupper((int)elem_type[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 = 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 = 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 = 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 = 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 */ { elem_blk_parms[i].elem_type_val = TRISHELL; elem_blk_parms[i].num_nodes_per_side[0] = elem_blk_parms[i].num_nodes_per_elem; } } else if (strncmp(elem_blk_parms[i].elem_type,"SHELL",3) == 0) { elem_blk_parms[i].elem_type_val = SHELL; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 2) { /* 2d SHELL; same as BEAM or TRUSS or BAR */ elem_blk_parms[i].num_nodes_per_side[0] = 2; elem_blk_parms[i].elem_type_val = BEAM; } 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 = 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 = 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 = 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; sprintf(errmsg, "Warning: WEDGE%d is assumed to have %d nodes per face", elem_blk_parms[i].num_nodes_per_elem, elem_blk_parms[i].num_nodes_per_side[0]); ex_err("ex_cvt_nodes_to_sides",errmsg,EX_MSG); } else if (strncmp(elem_blk_parms[i].elem_type,"PYRAMID",3) == 0) { elem_blk_parms[i].elem_type_val = 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; sprintf(errmsg, "Warning: PYRAMID%d is assumed to have %d nodes per face", elem_blk_parms[i].num_nodes_per_elem, elem_blk_parms[i].num_nodes_per_side[0]); ex_err("ex_cvt_nodes_to_sides",errmsg,EX_MSG); } else if (strncmp(elem_blk_parms[i].elem_type,"BEAM",3) == 0) { elem_blk_parms[i].elem_type_val = 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 = 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 = NULL_ELEMENT; /* set side set node stride */ elem_blk_parms[i].num_nodes_per_side[0] = 0; } else { /* unsupported element type; no problem if no sides specified for this element block */ elem_blk_parms[i].elem_type_val = UNK; elem_blk_parms[i].num_nodes_per_side[0] = 0; } elem_blk_parms[i].elem_blk_id = elem_blk_ids[i]; /* 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*sizeof(int)))) { free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); exerrval = EX_MEMFAIL; sprintf(errmsg, "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); return (EX_FATAL); } /* Allocate space for the ss element to node list index array */ if (!(ss_elem_node_ndx=malloc((tot_num_ss_elem+1)*sizeof(int)))) { free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); 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_cvt_nodes_to_sides",errmsg,exerrval); return (EX_FATAL); } /* 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)))) { free(ss_elem_ndx); exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for element type flag array for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); return (EX_FATAL); } elem_ctr = num_elem_per_set[0]; same_elem_type[0] = TRUE; for (i=0,k=0;i<tot_num_ss_elem;i++) { for (j=0; j<num_elem_blks; j++) { if (side_sets_elem_list[i] <= elem_blk_parms[j].elem_ctr) break; } 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 += num_elem_per_set[++k]; el_type = elem_blk_parms[j].elem_type_val; same_elem_type[k] = TRUE; } if (el_type != elem_blk_parms[j].elem_type_val) same_elem_type[k] = FALSE; } /* Build side set element to node list index and side set element parameter index. */ node_ctr = 0; elem_ctr = num_elem_per_set[0]; for (i=0,k=0;i<tot_num_ss_elem;i++) { for (j=0; j<num_elem_blks; j++) { if (side_sets_elem_list[i] <= elem_blk_parms[j].elem_ctr) { ss_parm_ndx[i] = j; /* assign parameter block index */ break; } } 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 (num_elem_per_set[++k] == 0); elem_ctr += num_elem_per_set[k]; } /* determine number of nodes per side */ if (((num_nodes_per_set[k] % num_elem_per_set[k]) == 0) && (same_elem_type[k])) { /* all side set elements are same type */ node_ctr += num_nodes_per_set[k] /num_elem_per_set[k]; } else { node_ctr += elem_blk_parms[j].num_nodes_per_side[0]; } } ss_elem_node_ndx[i] = node_ctr; /* assign node list index */ free(same_elem_type); /* All setup, ready to go ... */ elem_ctr=0; for (j=0; j < tot_num_ss_elem; j++) { if (side_sets_elem_list[ss_elem_ndx[j]] > 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[ss_parm_ndx[ss_elem_ndx[j]]].num_elem_in_blk* elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].num_nodes_per_elem* sizeof(int)))) { exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate space for connectivity array for file id %d", exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); return (EX_FATAL); } /* get connectivity array */ if (ex_get_elem_conn( exoid, elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id, connect) == -1) { sprintf(errmsg, "Error: failed to get connectivity array for elem blk %d for file id %d", elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); free(connect); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); return (EX_FATAL); } elem_ctr = elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].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. */ elem_num = side_sets_elem_list[ss_elem_ndx[j]]-1;/* element number 0-based*/ /* calculate the relative element number position in it's block*/ elem_num_pos = elem_num - (elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_ctr - elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].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[ss_parm_ndx[ss_elem_ndx[j]]].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 (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]] == connect[num_nodes_per_elem*(elem_num_pos)+n]) { switch (elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_type_val) { case CIRCLE: case SPHERE: { /* simple case: 1st node number is same as side # */ side_sets_side_list[ss_elem_ndx[j]] = n+1; break; } case QUAD: case TRIANGLE: case TRUSS: case BEAM: { /* simple case: 1st node number is same as side # */ side_sets_side_list[ss_elem_ndx[j]] = n+1; break; } case TRISHELL: { /* use table to find which node to compare to next */ num_node_per_side = ss_elem_node_ndx[ss_elem_ndx[j]+1] - ss_elem_node_ndx[ss_elem_ndx[j]]; if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (trishell_table[0][2*n]-1)]) { /* Assume only front or back, no edges... */ side_sets_side_list[ss_elem_ndx[j]] = trishell_table[1][2*n]; } else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (trishell_table[0][2*n+1]-1)]) { /* Assume only front or back, no edges... */ side_sets_side_list[ss_elem_ndx[j]] = trishell_table[1][2*n+1]; } else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (trishell_table[0][2*n+2]-1)]) { /* Assume only front or back, no edges... */ side_sets_side_list[ss_elem_ndx[j]] = trishell_table[1][2*n+2]; } else { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: failed to find TRIANGULAR SHELL element %d, node %d in connectivity array %d for file id %d", side_sets_elem_list[ss_elem_ndx[j]], side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1], elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); free(connect); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); return (EX_FATAL); } break; } case SHELL: { /* use table to find which node to compare to next */ num_node_per_side = ss_elem_node_ndx[ss_elem_ndx[j]+1] - ss_elem_node_ndx[ss_elem_ndx[j]]; if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (shell_table[0][2*n]-1)]) { if (num_node_per_side >= 4) /* 4- or 8-node side (front or back face) */ side_sets_side_list[ss_elem_ndx[j]] = shell_table[1][2*n]; else /* 2- or 3-node side (edge of shell) */ side_sets_side_list[ss_elem_ndx[j]] = shell_edge_table[1][2*n]; } else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (shell_table[0][2*n+1]-1)]) { if (num_node_per_side >= 4) /* 4- or 8-node side (front or back face) */ side_sets_side_list[ss_elem_ndx[j]] = shell_table[1][2*n+1]; else /* 2- or 3-node side (edge of shell) */ side_sets_side_list[ss_elem_ndx[j]]=shell_edge_table[1][2*n+1]; } else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (shell_table[0][2*n+2]-1)]) { if (num_node_per_side >= 4) /* 4- or 8-node side (front or back face) */ side_sets_side_list[ss_elem_ndx[j]] = shell_table[1][2*n+2]; else /* 2- or 3-node side (edge of shell) */ side_sets_side_list[ss_elem_ndx[j]]=shell_edge_table[1][2*n+2]; } else { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: failed to find SHELL element %d, node %d in connectivity array %d for file id %d", side_sets_elem_list[ss_elem_ndx[j]], side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1], elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); free(connect); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); return (EX_FATAL); } break; } case HEX: { /* use table to find which node to compare to next */ if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (hex_table[0][3*n]-1)]) side_sets_side_list[ss_elem_ndx[j]] = hex_table[1][3*n]; else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (hex_table[0][3*n+1]-1)]) side_sets_side_list[ss_elem_ndx[j]] = hex_table[1][3*n+1]; else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (hex_table[0][3*n+2]-1)]) side_sets_side_list[ss_elem_ndx[j]] = hex_table[1][3*n+2]; else { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: failed to find HEX element %d, node %d in connectivity array %d for file id %d", side_sets_elem_list[ss_elem_ndx[j]], side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1], elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); free(connect); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); return (EX_FATAL); } break; } case TETRA: { /* use table to find which node to compare to next */ if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (tetra_table[0][3*n]-1)]) side_sets_side_list[ss_elem_ndx[j]] = tetra_table[1][3*n]; else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (tetra_table[0][3*n+1]-1)]) side_sets_side_list[ss_elem_ndx[j]] = tetra_table[1][3*n+1]; else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (tetra_table[0][3*n+2]-1)]) side_sets_side_list[ss_elem_ndx[j]] = tetra_table[1][3*n+2]; else { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: failed to find TETRA element %d, node %d in connectivity array %d for file id %d", side_sets_elem_list[ss_elem_ndx[j]], side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1], elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); free(connect); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); return (EX_FATAL); } break; } case PYRAMID: { /* NOTE: PYRAMID elements in side set node lists are currently not supported */ exerrval = EX_BADPARAM; sprintf(errmsg, "ERROR: unsupported PYRAMID element found in side set node list in file id %d", exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); free(connect); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); return (EX_FATAL); } case WEDGE: { #if 1 /* NOTE: WEDGE elements in side set node lists are currently not supported */ exerrval = EX_BADPARAM; sprintf(errmsg, "ERROR: unsupported WEDGE element found in side set node list in file id %d", exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); free(connect); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); return (EX_FATAL); #else /* use wedge_table to find which node to compare to next */ /* This section is commented out because Wedges are no longer supported !!!*/ if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (wedge_table[0][3*n]-1)]) side_sets_side_list[ss_elem_ndx[j]] = wedge_table[1][3*n]; else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (wedge_table[0][3*n+1]-1)]) side_sets_side_list[ss_elem_ndx[j]] = wedge_table[1][3*n+1]; else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] == connect[num_nodes_per_elem*(elem_num_pos)+ (wedge_table[0][3*n+2]-1)]) side_sets_side_list[ss_elem_ndx[j]] = wedge_table[1][3*n+2]; else { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: failed to find WEDGE element %d, node %d in connectivity array %d for file id %d", side_sets_elem_list[ss_elem_ndx[j]], side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1], elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); free(connect); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); return (EX_FATAL); } break; #endif } default: { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: %s is an unsupported element type", elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_type); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); return(EX_FATAL); } } break; /* done with this element */ } } if (n >= num_nodes_per_elem) /* did we find the node? */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: failed to find element %d, node %d in element block %d for file id %d", side_sets_elem_list[ss_elem_ndx[j]], side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]], elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id, exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); free(connect); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); return (EX_FATAL); } } /* All done: release connectivity array space, element block ids array, element block parameters array, and side set element index array */ free(connect); free(ss_elem_node_ndx); free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); return (EX_NOERR); }
int read_mesh(const std::string &exo_file, Problem_Description* problem, Mesh_Description<INT>* mesh, Weight_Description<INT>* weight ) { float version, *xptr, *yptr, *zptr; char elem_type[MAX_STR_LENGTH+1]; E_Type blk_elem_type; /*---------------------------Execution Begins--------------------------------*/ /* Open the ExodusII file */ int exoid, cpu_ws=0, io_ws=0; int mode = EX_READ | problem->int64api; if((exoid=ex_open(exo_file.c_str(), mode, &cpu_ws, &io_ws, &version)) < 0) { Gen_Error(0, "fatal: unable to open ExodusII mesh file"); return 0; } /* Read the coordinates, if desired */ xptr = yptr = zptr = NULL; if(problem->read_coords == ELB_TRUE) { switch(mesh->num_dims) { case 3: zptr = (mesh->coords)+2*(mesh->num_nodes); /* FALLTHRU */ case 2: yptr = (mesh->coords)+(mesh->num_nodes); /* FALLTHRU */ case 1: xptr = mesh->coords; } if(ex_get_coord(exoid, xptr, yptr, zptr) < 0) { Gen_Error(0, "fatal: unable to read coordinate values for mesh"); return 0; } } /* End "if(problem->read_coords == ELB_TRUE)" */ /* Read the element block IDs */ std::vector<INT> el_blk_ids(mesh->num_el_blks); std::vector<INT> el_blk_cnts(mesh->num_el_blks); if(ex_get_elem_blk_ids(exoid, &el_blk_ids[0]) < 0) { Gen_Error(0, "fatal: unable to read element block IDs"); return 0; } /* Read the element connectivity */ size_t gelem_cnt=0; for(size_t cnt=0; cnt < mesh->num_el_blks; cnt++) { INT nodes_per_elem, num_attr; if(ex_get_elem_block(exoid, el_blk_ids[cnt], elem_type, &(el_blk_cnts[cnt]), &nodes_per_elem, &num_attr) < 0) { Gen_Error(0, "fatal: unable to read element block"); return 0; } blk_elem_type = get_elem_type(elem_type, nodes_per_elem, mesh->num_dims); INT *blk_connect = (INT*)malloc(sizeof(INT)*el_blk_cnts[cnt]*nodes_per_elem); if(!blk_connect) { Gen_Error(0, "fatal: insufficient memory"); return 0; } /* Get the connectivity for this element block */ if(ex_get_elem_conn(exoid, el_blk_ids[cnt], blk_connect) < 0) { Gen_Error(0, "fatal: failed to get element connectivity"); return 0; } /* find out if this element block is weighted */ int wgt = -1; if (weight->type & EL_BLK) wgt = in_list(el_blk_ids[cnt], weight->elemblk); /* Fill the 2D global connectivity array */ if (((problem->type == ELEMENTAL) && (weight->type & EL_BLK)) || ((problem->type == NODAL) && (weight->type & EL_BLK))) { for(int64_t cnt2=0; cnt2 < el_blk_cnts[cnt]; cnt2++) { mesh->elem_type[gelem_cnt] = blk_elem_type; /* while going through the blocks, take care of the weighting */ if ((problem->type == ELEMENTAL) && (weight->type & EL_BLK)) { /* is this block weighted */ if (wgt >= 0) { /* check if there is a read value */ if (weight->vertices[gelem_cnt] >= 1) { /* and if it should be overwritten */ if (weight->ow_read) weight->vertices[gelem_cnt] = weight->elemblk_wgt[wgt]; } else weight->vertices[gelem_cnt] = weight->elemblk_wgt[wgt]; } else { /* now check if this weight has been initialized */ if (weight->vertices[gelem_cnt] < 1) weight->vertices[gelem_cnt] = 1; } } for(int64_t cnt3=0; cnt3 < nodes_per_elem; cnt3++) { INT node = blk_connect[cnt3 + cnt2*nodes_per_elem] - 1; assert(node >= 0); mesh->connect[gelem_cnt][cnt3] = node; /* deal with the weighting if necessary */ if ((problem->type == NODAL) && (weight->type & EL_BLK)) { /* is this block weighted */ if (wgt >= 0) { /* check if I read an exodus file */ if (weight->type & READ_EXO) { /* check if it can be overwritten */ if (weight->ow_read) { /* check if it has been overwritten already */ if (weight->ow[node]) { weight->vertices[node] = MAX(weight->vertices[node], weight->elemblk_wgt[wgt]); } else { weight->vertices[node] = weight->elemblk_wgt[wgt]; weight->ow[node] = 1; /* read value has been overwritten */ } } } else { weight->vertices[node] = MAX(weight->vertices[node], weight->elemblk_wgt[wgt]); } } else { /* now check if this weight has been initialized */ if (weight->vertices[node] < 1) weight->vertices[node] = 1; } } } gelem_cnt++; } } else { // No weights... for (int64_t cnt2=0; cnt2 < el_blk_cnts[cnt]; cnt2++) { mesh->elem_type[gelem_cnt] = blk_elem_type; for (int64_t cnt3=0; cnt3 < nodes_per_elem; cnt3++) { INT node = blk_connect[cnt2*nodes_per_elem + cnt3] - 1; assert(node >= 0); mesh->connect[gelem_cnt][cnt3] = node; } gelem_cnt++; } } /* Free up memory */ free(blk_connect); } /* End "for(cnt=0; cnt < mesh->num_el_blks; cnt++)" */ /* if there is a group designator, then parse it here */ if (problem->groups != NULL) { if (!parse_groups(&el_blk_ids[0], &el_blk_cnts[0], mesh, problem)) { Gen_Error(0, "fatal: unable to parse group designator"); ex_close(exoid); return 0; } } else problem->num_groups = 1; /* there is always one group */ /* Close the ExodusII file */ if(ex_close(exoid) < 0) Gen_Error(0, "warning: failed to close ExodusII mesh file"); return 1; } /*---------------------------End read_mesh()-------------------------------*/
int main(int argc, char **argv) { int exoid, num_dim, num_nodes, num_elem, num_elem_blk, num_node_sets; int num_side_sets, error; int i, j, k, node_ctr; int *elem_map, *connect, *node_list, *node_ctr_list, *elem_list, *side_list; int *ids; int *num_nodes_per_set = NULL; int *num_elem_per_set = NULL; int *num_df_per_set = NULL; int *node_ind = NULL; int *elem_ind = NULL; int *df_ind = NULL; int num_qa_rec, num_info; int num_glo_vars, num_nod_vars, num_ele_vars; int num_nset_vars, num_sset_vars; int *truth_tab; int num_time_steps; int *num_elem_in_block = NULL; int *num_nodes_per_elem = NULL; int *num_attr = NULL; int num_nodes_in_set, num_elem_in_set; int num_sides_in_set, num_df_in_set; int list_len, elem_list_len, node_list_len, df_list_len; int node_num, time_step, var_index, beg_time, end_time, elem_num; int CPU_word_size, IO_word_size; int num_props, prop_value, *prop_values; int idum; float time_value, *time_values, *var_values; float *x, *y, *z; float *attrib, *dist_fact; float version, fdum; char *coord_names[3], *qa_record[2][4], *info[3], *var_names[3]; char *block_names[10], *nset_names[10], *sset_names[10]; char *attrib_names[10]; char name[MAX_STR_LENGTH + 1]; char title[MAX_LINE_LENGTH + 1], elem_type[MAX_STR_LENGTH + 1]; char title_chk[MAX_LINE_LENGTH + 1]; char *cdum = 0; char *prop_names[3]; CPU_word_size = 0; /* sizeof(float) */ IO_word_size = 0; /* use what is stored in file */ ex_opts(EX_VERBOSE | EX_ABORT); /* open EXODUS II files */ exoid = ex_open("test.exo", /* filename path */ EX_READ, /* access mode = READ */ &CPU_word_size, /* CPU word size */ &IO_word_size, /* IO word size */ &version); /* ExodusII library version */ printf("\nafter ex_open\n"); if (exoid < 0) exit(1); printf("test.exo is an EXODUSII file; version %4.2f\n", version); /* printf (" CPU word size %1d\n",CPU_word_size); */ printf(" I/O word size %1d\n", IO_word_size); ex_inquire(exoid, EX_INQ_API_VERS, &idum, &version, cdum); printf("EXODUSII API; version %4.2f\n", version); ex_inquire(exoid, EX_INQ_LIB_VERS, &idum, &version, cdum); printf("EXODUSII Library API; version %4.2f (%d)\n", version, idum); /* read database parameters */ error = ex_get_init(exoid, title, &num_dim, &num_nodes, &num_elem, &num_elem_blk, &num_node_sets, &num_side_sets); printf("after ex_get_init, error = %3d\n", error); printf("database parameters:\n"); printf("title = '%s'\n", title); printf("num_dim = %3d\n", num_dim); printf("num_nodes = %3d\n", num_nodes); printf("num_elem = %3d\n", num_elem); printf("num_elem_blk = %3d\n", num_elem_blk); printf("num_node_sets = %3d\n", num_node_sets); printf("num_side_sets = %3d\n", num_side_sets); /* Check that ex_inquire gives same title */ error = ex_inquire(exoid, EX_INQ_TITLE, &idum, &fdum, title_chk); printf(" after ex_inquire, error = %d\n", error); if (strcmp(title, title_chk) != 0) { printf("error in ex_inquire for EX_INQ_TITLE\n"); } /* read nodal coordinates values and names from database */ x = (float *)calloc(num_nodes, sizeof(float)); if (num_dim >= 2) y = (float *)calloc(num_nodes, sizeof(float)); else y = 0; if (num_dim >= 3) z = (float *)calloc(num_nodes, sizeof(float)); else z = 0; error = ex_get_coord(exoid, x, y, z); printf("\nafter ex_get_coord, error = %3d\n", error); printf("x coords = \n"); for (i = 0; i < num_nodes; i++) { printf("%5.1f\n", x[i]); } if (num_dim >= 2) { printf("y coords = \n"); for (i = 0; i < num_nodes; i++) { printf("%5.1f\n", y[i]); } } if (num_dim >= 3) { printf("z coords = \n"); for (i = 0; i < num_nodes; i++) { printf("%5.1f\n", z[i]); } } /* error = ex_get_1_coord (exoid, 2, x, y, z); printf ("\nafter ex_get_1_coord, error = %3d\n", error); printf ("x coord of node 2 = \n"); printf ("%f \n", x[0]); printf ("y coord of node 2 = \n"); printf ("%f \n", y[0]); */ free(x); if (num_dim >= 2) free(y); if (num_dim >= 3) free(z); for (i = 0; i < num_dim; i++) { coord_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_coord_names(exoid, coord_names); printf("\nafter ex_get_coord_names, error = %3d\n", error); printf("x coord name = '%s'\n", coord_names[0]); if (num_dim > 1) printf("y coord name = '%s'\n", coord_names[1]); if (num_dim > 2) printf("z coord name = '%s'\n", coord_names[2]); for (i = 0; i < num_dim; i++) free(coord_names[i]); { int num_attrs = 0; error = ex_get_attr_param(exoid, EX_NODAL, 0, &num_attrs); printf(" after ex_get_attr_param, error = %d\n", error); printf("num nodal attributes = %d\n", num_attrs); if (num_attrs > 0) { for (j = 0; j < num_attrs; j++) { attrib_names[j] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_attr_names(exoid, EX_NODAL, 0, attrib_names); printf(" after ex_get_attr_names, error = %d\n", error); if (error == 0) { attrib = (float *)calloc(num_nodes, sizeof(float)); for (j = 0; j < num_attrs; j++) { printf("nodal attribute %d = '%s'\n", j, attrib_names[j]); error = ex_get_one_attr(exoid, EX_NODAL, 0, j + 1, attrib); printf(" after ex_get_one_attr, error = %d\n", error); for (i = 0; i < num_nodes; i++) { printf("%5.1f\n", attrib[i]); } free(attrib_names[j]); } free(attrib); } } } /* read element order map */ elem_map = (int *)calloc(num_elem, sizeof(int)); error = ex_get_map(exoid, elem_map); printf("\nafter ex_get_map, error = %3d\n", error); for (i = 0; i < num_elem; i++) { printf("elem_map(%d) = %d \n", i, elem_map[i]); } free(elem_map); /* read element block parameters */ if (num_elem_blk > 0) { ids = (int *)calloc(num_elem_blk, sizeof(int)); num_elem_in_block = (int *)calloc(num_elem_blk, sizeof(int)); num_nodes_per_elem = (int *)calloc(num_elem_blk, sizeof(int)); num_attr = (int *)calloc(num_elem_blk, sizeof(int)); error = ex_get_elem_blk_ids(exoid, ids); printf("\nafter ex_get_elem_blk_ids, error = %3d\n", error); for (i = 0; i < num_elem_blk; i++) { block_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_names(exoid, EX_ELEM_BLOCK, block_names); printf("\nafter ex_get_names, error = %3d\n", error); for (i = 0; i < num_elem_blk; i++) { ex_get_name(exoid, EX_ELEM_BLOCK, ids[i], name); if (strcmp(name, block_names[i]) != 0) { printf("error in ex_get_name for block id %d\n", ids[i]); } error = ex_get_elem_block(exoid, ids[i], elem_type, &(num_elem_in_block[i]), &(num_nodes_per_elem[i]), &(num_attr[i])); printf("\nafter ex_get_elem_block, error = %d\n", error); printf("element block id = %2d\n", ids[i]); printf("element type = '%s'\n", elem_type); printf("num_elem_in_block = %2d\n", num_elem_in_block[i]); printf("num_nodes_per_elem = %2d\n", num_nodes_per_elem[i]); printf("num_attr = %2d\n", num_attr[i]); printf("name = '%s'\n", block_names[i]); free(block_names[i]); } /* read element block properties */ error = ex_inquire(exoid, EX_INQ_EB_PROP, &num_props, &fdum, cdum); printf("\nafter ex_inquire, error = %d\n", error); printf("\nThere are %2d properties for each element block\n", num_props); for (i = 0; i < num_props; i++) { prop_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_prop_names(exoid, EX_ELEM_BLOCK, prop_names); printf("after ex_get_prop_names, error = %d\n", error); for (i = 1; i < num_props; i++) /* Prop 1 is id; skip that here */ { for (j = 0; j < num_elem_blk; j++) { error = ex_get_prop(exoid, EX_ELEM_BLOCK, ids[j], prop_names[i], &prop_value); if (error == 0) printf("element block %2d, property(%2d): '%s'= %5d\n", j + 1, i + 1, prop_names[i], prop_value); else printf("after ex_get_prop, error = %d\n", error); } } for (i = 0; i < num_props; i++) free(prop_names[i]); } /* read element connectivity */ for (i = 0; i < num_elem_blk; i++) { if (num_elem_in_block[i] > 0) { connect = (int *)calloc((num_nodes_per_elem[i] * num_elem_in_block[i]), sizeof(int)); error = ex_get_elem_conn(exoid, ids[i], connect); printf("\nafter ex_get_elem_conn, error = %d\n", error); printf("connect array for elem block %2d\n", ids[i]); for (j = 0; j < num_nodes_per_elem[i]; j++) { printf("%3d\n", connect[j]); } /* error = ex_get_1_elem_conn (exoid, 1, ids[i], connect); printf ("\nafter ex_get_elem_conn, error = %d\n", error); printf ("node list for first element of element block %d \n ", ids[i]); for (j=0; j<num_nodes_per_elem[i]; j++) { printf ("%d \n", connect[j]); } */ free(connect); } } /* read element block attributes */ for (i = 0; i < num_elem_blk; i++) { if (num_elem_in_block[i] > 0) { for (j = 0; j < num_attr[i]; j++) attrib_names[j] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); attrib = (float *)calloc(num_attr[i] * num_elem_in_block[i], sizeof(float)); error = ex_get_elem_attr(exoid, ids[i], attrib); printf("\n after ex_get_elem_attr, error = %d\n", error); if (error == 0) { error = ex_get_elem_attr_names(exoid, ids[i], attrib_names); printf(" after ex_get_elem_attr_names, error = %d\n", error); if (error == 0) { printf("element block %d attribute '%s' = %6.4f\n", ids[i], attrib_names[0], *attrib); } } free(attrib); for (j = 0; j < num_attr[i]; j++) free(attrib_names[j]); } } if (num_elem_blk > 0) { free(ids); free(num_nodes_per_elem); free(num_attr); } /* read individual node sets */ if (num_node_sets > 0) { ids = (int *)calloc(num_node_sets, sizeof(int)); error = ex_get_node_set_ids(exoid, ids); printf("\nafter ex_get_node_set_ids, error = %3d\n", error); for (i = 0; i < num_node_sets; i++) { nset_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_names(exoid, EX_NODE_SET, nset_names); printf("\nafter ex_get_names, error = %3d\n", error); for (i = 0; i < num_node_sets; i++) { ex_get_name(exoid, EX_NODE_SET, ids[i], name); if (strcmp(name, nset_names[i]) != 0) { printf("error in ex_get_name for nodeset id %d\n", ids[i]); } error = ex_get_node_set_param(exoid, ids[i], &num_nodes_in_set, &num_df_in_set); printf("\nafter ex_get_node_set_param, error = %3d\n", error); printf("\nnode set %2d parameters: \n", ids[i]); printf("num_nodes = %2d\n", num_nodes_in_set); printf("name = '%s'\n", nset_names[i]); free(nset_names[i]); node_list = (int *)calloc(num_nodes_in_set, sizeof(int)); dist_fact = (float *)calloc(num_nodes_in_set, sizeof(float)); error = ex_get_node_set(exoid, ids[i], node_list); printf("\nafter ex_get_node_set, error = %3d\n", error); if (num_df_in_set > 0) { error = ex_get_node_set_dist_fact(exoid, ids[i], dist_fact); printf("\nafter ex_get_node_set_dist_fact, error = %3d\n", error); } printf("\nnode list for node set %2d\n", ids[i]); for (j = 0; j < num_nodes_in_set; j++) { printf("%3d\n", node_list[j]); } if (num_df_in_set > 0) { printf("dist factors for node set %2d\n", ids[i]); for (j = 0; j < num_df_in_set; j++) { printf("%5.2f\n", dist_fact[j]); } } else printf("no dist factors for node set %2d\n", ids[i]); free(node_list); free(dist_fact); { int num_attrs = 0; error = ex_get_attr_param(exoid, EX_NODE_SET, ids[i], &num_attrs); printf(" after ex_get_attr_param, error = %d\n", error); printf("num nodeset attributes for nodeset %d = %d\n", ids[i], num_attrs); if (num_attrs > 0) { for (j = 0; j < num_attrs; j++) { attrib_names[j] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_attr_names(exoid, EX_NODE_SET, ids[i], attrib_names); printf(" after ex_get_attr_names, error = %d\n", error); if (error == 0) { attrib = (float *)calloc(num_nodes_in_set, sizeof(float)); for (j = 0; j < num_attrs; j++) { printf("nodeset attribute %d = '%s'\n", j, attrib_names[j]); error = ex_get_one_attr(exoid, EX_NODE_SET, ids[i], j + 1, attrib); printf(" after ex_get_one_attr, error = %d\n", error); for (k = 0; k < num_nodes_in_set; k++) { printf("%5.1f\n", attrib[k]); } free(attrib_names[j]); } free(attrib); } } } } free(ids); /* read node set properties */ error = ex_inquire(exoid, EX_INQ_NS_PROP, &num_props, &fdum, cdum); printf("\nafter ex_inquire, error = %d\n", error); printf("\nThere are %2d properties for each node set\n", num_props); for (i = 0; i < num_props; i++) { prop_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } prop_values = (int *)calloc(num_node_sets, sizeof(int)); error = ex_get_prop_names(exoid, EX_NODE_SET, prop_names); printf("after ex_get_prop_names, error = %d\n", error); for (i = 0; i < num_props; i++) { error = ex_get_prop_array(exoid, EX_NODE_SET, prop_names[i], prop_values); if (error == 0) for (j = 0; j < num_node_sets; j++) printf("node set %2d, property(%2d): '%s'= %5d\n", j + 1, i + 1, prop_names[i], prop_values[j]); else printf("after ex_get_prop_array, error = %d\n", error); } for (i = 0; i < num_props; i++) free(prop_names[i]); free(prop_values); /* read concatenated node sets; this produces the same information as * the above code which reads individual node sets */ error = ex_inquire(exoid, EX_INQ_NODE_SETS, &num_node_sets, &fdum, cdum); printf("\nafter ex_inquire, error = %3d\n", error); ids = (int *)calloc(num_node_sets, sizeof(int)); num_nodes_per_set = (int *)calloc(num_node_sets, sizeof(int)); num_df_per_set = (int *)calloc(num_node_sets, sizeof(int)); node_ind = (int *)calloc(num_node_sets, sizeof(int)); df_ind = (int *)calloc(num_node_sets, sizeof(int)); error = ex_inquire(exoid, EX_INQ_NS_NODE_LEN, &list_len, &fdum, cdum); printf("\nafter ex_inquire: EX_INQ_NS_NODE_LEN = %d, error = %3d\n", list_len, error); node_list = (int *)calloc(list_len, sizeof(int)); error = ex_inquire(exoid, EX_INQ_NS_DF_LEN, &list_len, &fdum, cdum); printf("\nafter ex_inquire: EX_INQ_NS_DF_LEN = %d, error = %3d\n", list_len, error); dist_fact = (float *)calloc(list_len, sizeof(float)); error = ex_get_concat_node_sets(exoid, ids, num_nodes_per_set, num_df_per_set, node_ind, df_ind, node_list, dist_fact); printf("\nafter ex_get_concat_node_sets, error = %3d\n", error); printf("\nconcatenated node set info\n"); printf("ids = \n"); for (i = 0; i < num_node_sets; i++) printf("%3d\n", ids[i]); printf("num_nodes_per_set = \n"); for (i = 0; i < num_node_sets; i++) printf("%3d\n", num_nodes_per_set[i]); printf("node_ind = \n"); for (i = 0; i < num_node_sets; i++) printf("%3d\n", node_ind[i]); printf("node_list = \n"); for (i = 0; i < list_len; i++) printf("%3d\n", node_list[i]); printf("dist_fact = \n"); for (i = 0; i < list_len; i++) printf("%5.3f\n", dist_fact[i]); free(ids); free(df_ind); free(node_ind); free(num_df_per_set); free(node_list); free(dist_fact); } /* read individual side sets */ if (num_side_sets > 0) { ids = (int *)calloc(num_side_sets, sizeof(int)); error = ex_get_side_set_ids(exoid, ids); printf("\nafter ex_get_side_set_ids, error = %3d\n", error); for (i = 0; i < num_side_sets; i++) { sset_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_names(exoid, EX_SIDE_SET, sset_names); printf("\nafter ex_get_names, error = %3d\n", error); for (i = 0; i < num_side_sets; i++) { ex_get_name(exoid, EX_SIDE_SET, ids[i], name); if (strcmp(name, sset_names[i]) != 0) { printf("error in ex_get_name for sideset id %d\n", ids[i]); } error = ex_get_side_set_param(exoid, ids[i], &num_sides_in_set, &num_df_in_set); printf("\nafter ex_get_side_set_param, error = %3d\n", error); printf("side set %2d parameters:\n", ids[i]); printf("name = '%s'\n", sset_names[i]); printf("num_sides = %3d\n", num_sides_in_set); printf("num_dist_factors = %3d\n", num_df_in_set); free(sset_names[i]); /* Note: The # of elements is same as # of sides! */ num_elem_in_set = num_sides_in_set; elem_list = (int *)calloc(num_elem_in_set, sizeof(int)); side_list = (int *)calloc(num_sides_in_set, sizeof(int)); node_ctr_list = (int *)calloc(num_elem_in_set, sizeof(int)); node_list = (int *)calloc(num_elem_in_set * 21, sizeof(int)); dist_fact = (float *)calloc(num_df_in_set, sizeof(float)); error = ex_get_side_set(exoid, ids[i], elem_list, side_list); printf("\nafter ex_get_side_set, error = %3d\n", error); error = ex_get_side_set_node_list(exoid, ids[i], node_ctr_list, node_list); printf("\nafter ex_get_side_set_node_list, error = %3d\n", error); if (num_df_in_set > 0) { error = ex_get_side_set_dist_fact(exoid, ids[i], dist_fact); printf("\nafter ex_get_side_set_dist_fact, error = %3d\n", error); } printf("element list for side set %2d\n", ids[i]); for (j = 0; j < num_elem_in_set; j++) { printf("%3d\n", elem_list[j]); } printf("side list for side set %2d\n", ids[i]); for (j = 0; j < num_sides_in_set; j++) { printf("%3d\n", side_list[j]); } node_ctr = 0; printf("node list for side set %2d\n", ids[i]); for (k = 0; k < num_elem_in_set; k++) { for (j = 0; j < node_ctr_list[k]; j++) { printf("%3d\n", node_list[node_ctr + j]); } node_ctr += node_ctr_list[k]; } if (num_df_in_set > 0) { printf("dist factors for side set %2d\n", ids[i]); for (j = 0; j < num_df_in_set; j++) { printf("%5.3f\n", dist_fact[j]); } } else printf("no dist factors for side set %2d\n", ids[i]); free(elem_list); free(side_list); free(node_ctr_list); free(node_list); free(dist_fact); } /* read side set properties */ error = ex_inquire(exoid, EX_INQ_SS_PROP, &num_props, &fdum, cdum); printf("\nafter ex_inquire, error = %d\n", error); printf("\nThere are %2d properties for each side set\n", num_props); for (i = 0; i < num_props; i++) { prop_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_prop_names(exoid, EX_SIDE_SET, prop_names); printf("after ex_get_prop_names, error = %d\n", error); for (i = 0; i < num_props; i++) { for (j = 0; j < num_side_sets; j++) { error = ex_get_prop(exoid, EX_SIDE_SET, ids[j], prop_names[i], &prop_value); if (error == 0) printf("side set %2d, property(%2d): '%s'= %5d\n", j + 1, i + 1, prop_names[i], prop_value); else printf("after ex_get_prop, error = %d\n", error); } } for (i = 0; i < num_props; i++) free(prop_names[i]); free(ids); error = ex_inquire(exoid, EX_INQ_SIDE_SETS, &num_side_sets, &fdum, cdum); printf("\nafter ex_inquire: EX_INQ_SIDE_SETS = %d, error = %d\n", num_side_sets, error); if (num_side_sets > 0) { error = ex_inquire(exoid, EX_INQ_SS_ELEM_LEN, &elem_list_len, &fdum, cdum); printf("\nafter ex_inquire: EX_INQ_SS_ELEM_LEN = %d, error = %d\n", elem_list_len, error); error = ex_inquire(exoid, EX_INQ_SS_NODE_LEN, &node_list_len, &fdum, cdum); printf("\nafter ex_inquire: EX_INQ_SS_NODE_LEN = %d, error = %d\n", node_list_len, error); error = ex_inquire(exoid, EX_INQ_SS_DF_LEN, &df_list_len, &fdum, cdum); printf("\nafter ex_inquire: EX_INQ_SS_DF_LEN = %d, error = %d\n", df_list_len, error); } /* read concatenated side sets; this produces the same information as * the above code which reads individual side sets */ /* concatenated side set read */ if (num_side_sets > 0) { ids = (int *)calloc(num_side_sets, sizeof(int)); num_elem_per_set = (int *)calloc(num_side_sets, sizeof(int)); num_df_per_set = (int *)calloc(num_side_sets, sizeof(int)); elem_ind = (int *)calloc(num_side_sets, sizeof(int)); df_ind = (int *)calloc(num_side_sets, sizeof(int)); elem_list = (int *)calloc(elem_list_len, sizeof(int)); side_list = (int *)calloc(elem_list_len, sizeof(int)); dist_fact = (float *)calloc(df_list_len, sizeof(float)); error = ex_get_concat_side_sets(exoid, ids, num_elem_per_set, num_df_per_set, elem_ind, df_ind, elem_list, side_list, dist_fact); printf("\nafter ex_get_concat_side_sets, error = %3d\n", error); printf("concatenated side set info\n"); printf("ids = \n"); for (i = 0; i < num_side_sets; i++) printf("%3d\n", ids[i]); printf("num_elem_per_set = \n"); for (i = 0; i < num_side_sets; i++) printf("%3d\n", num_elem_per_set[i]); printf("num_dist_per_set = \n"); for (i = 0; i < num_side_sets; i++) printf("%3d\n", num_df_per_set[i]); printf("elem_ind = \n"); for (i = 0; i < num_side_sets; i++) printf("%3d\n", elem_ind[i]); printf("dist_ind = \n"); for (i = 0; i < num_side_sets; i++) printf("%3d\n", df_ind[i]); printf("elem_list = \n"); for (i = 0; i < elem_list_len; i++) printf("%3d\n", elem_list[i]); printf("side_list = \n"); for (i = 0; i < elem_list_len; i++) printf("%3d\n", side_list[i]); printf("dist_fact = \n"); for (i = 0; i < df_list_len; i++) printf("%5.3f\n", dist_fact[i]); free(ids); free(num_df_per_set); free(df_ind); free(elem_ind); free(elem_list); free(side_list); free(dist_fact); } } /* end of concatenated side set read */ /* read QA records */ ex_inquire(exoid, EX_INQ_QA, &num_qa_rec, &fdum, cdum); for (i = 0; i < num_qa_rec; i++) { for (j = 0; j < 4; j++) { qa_record[i][j] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } } error = ex_get_qa(exoid, qa_record); printf("\nafter ex_get_qa, error = %3d\n", error); printf("QA records = \n"); for (i = 0; i < num_qa_rec; i++) { for (j = 0; j < 4; j++) { printf(" '%s'\n", qa_record[i][j]); free(qa_record[i][j]); } } /* read information records */ error = ex_inquire(exoid, EX_INQ_INFO, &num_info, &fdum, cdum); printf("\nafter ex_inquire, error = %3d\n", error); for (i = 0; i < num_info; i++) { info[i] = (char *)calloc((MAX_LINE_LENGTH + 1), sizeof(char)); } error = ex_get_info(exoid, info); printf("\nafter ex_get_info, error = %3d\n", error); printf("info records = \n"); for (i = 0; i < num_info; i++) { printf(" '%s'\n", info[i]); free(info[i]); } /* read global variables parameters and names */ error = ex_get_var_param(exoid, "g", &num_glo_vars); printf("\nafter ex_get_var_param, error = %3d\n", error); for (i = 0; i < num_glo_vars; i++) { var_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_var_names(exoid, "g", num_glo_vars, var_names); printf("\nafter ex_get_var_names, error = %3d\n", error); printf("There are %2d global variables; their names are :\n", num_glo_vars); for (i = 0; i < num_glo_vars; i++) { printf(" '%s'\n", var_names[i]); free(var_names[i]); } /* read nodal variables parameters and names */ num_nod_vars = 0; if (num_nodes > 0) { error = ex_get_var_param(exoid, "n", &num_nod_vars); printf("\nafter ex_get_var_param, error = %3d\n", error); for (i = 0; i < num_nod_vars; i++) { var_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_var_names(exoid, "n", num_nod_vars, var_names); printf("\nafter ex_get_var_names, error = %3d\n", error); printf("There are %2d nodal variables; their names are :\n", num_nod_vars); for (i = 0; i < num_nod_vars; i++) { printf(" '%s'\n", var_names[i]); free(var_names[i]); } } /* read element variables parameters and names */ num_ele_vars = 0; if (num_elem > 0) { error = ex_get_var_param(exoid, "e", &num_ele_vars); printf("\nafter ex_get_var_param, error = %3d\n", error); for (i = 0; i < num_ele_vars; i++) { var_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_var_names(exoid, "e", num_ele_vars, var_names); printf("\nafter ex_get_var_names, error = %3d\n", error); printf("There are %2d element variables; their names are :\n", num_ele_vars); for (i = 0; i < num_ele_vars; i++) { printf(" '%s'\n", var_names[i]); free(var_names[i]); } /* read element variable truth table */ if (num_ele_vars > 0) { truth_tab = (int *)calloc((num_elem_blk * num_ele_vars), sizeof(int)); error = ex_get_elem_var_tab(exoid, num_elem_blk, num_ele_vars, truth_tab); printf("\nafter ex_get_elem_var_tab, error = %3d\n", error); printf("This is the element variable truth table:\n"); k = 0; for (i = 0; i < num_elem_blk * num_ele_vars; i++) { printf("%2d\n", truth_tab[k++]); } free(truth_tab); } } /* read nodeset variables parameters and names */ num_nset_vars = 0; if (num_node_sets > 0) { error = ex_get_var_param(exoid, "m", &num_nset_vars); printf("\nafter ex_get_var_param, error = %3d\n", error); if (num_nset_vars > 0) { for (i = 0; i < num_nset_vars; i++) { var_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_var_names(exoid, "m", num_nset_vars, var_names); printf("\nafter ex_get_var_names, error = %3d\n", error); printf("There are %2d nodeset variables; their names are :\n", num_nset_vars); for (i = 0; i < num_nset_vars; i++) { printf(" '%s'\n", var_names[i]); free(var_names[i]); } /* read nodeset variable truth table */ if (num_nset_vars > 0) { truth_tab = (int *)calloc((num_node_sets * num_nset_vars), sizeof(int)); error = ex_get_nset_var_tab(exoid, num_node_sets, num_nset_vars, truth_tab); printf("\nafter ex_get_nset_var_tab, error = %3d\n", error); printf("This is the nodeset variable truth table:\n"); k = 0; for (i = 0; i < num_node_sets * num_nset_vars; i++) { printf("%2d\n", truth_tab[k++]); } free(truth_tab); } } } /* read sideset variables parameters and names */ num_sset_vars = 0; if (num_side_sets > 0) { error = ex_get_var_param(exoid, "s", &num_sset_vars); printf("\nafter ex_get_var_param, error = %3d\n", error); if (num_sset_vars > 0) { for (i = 0; i < num_sset_vars; i++) { var_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_var_names(exoid, "s", num_sset_vars, var_names); printf("\nafter ex_get_var_names, error = %3d\n", error); printf("There are %2d sideset variables; their names are :\n", num_sset_vars); for (i = 0; i < num_sset_vars; i++) { printf(" '%s'\n", var_names[i]); free(var_names[i]); } /* read sideset variable truth table */ if (num_sset_vars > 0) { truth_tab = (int *)calloc((num_side_sets * num_sset_vars), sizeof(int)); error = ex_get_sset_var_tab(exoid, num_side_sets, num_sset_vars, truth_tab); printf("\nafter ex_get_sset_var_tab, error = %3d\n", error); printf("This is the sideset variable truth table:\n"); k = 0; for (i = 0; i < num_side_sets * num_sset_vars; i++) { printf("%2d\n", truth_tab[k++]); } free(truth_tab); } } } /* determine how many time steps are stored */ error = ex_inquire(exoid, EX_INQ_TIME, &num_time_steps, &fdum, cdum); printf("\nafter ex_inquire, error = %3d\n", error); printf("There are %2d time steps in the database.\n", num_time_steps); /* read time value at one time step */ time_step = 3; error = ex_get_time(exoid, time_step, &time_value); printf("\nafter ex_get_time, error = %3d\n", error); printf("time value at time step %2d = %5.3f\n", time_step, time_value); /* read time values at all time steps */ time_values = (float *)calloc(num_time_steps, sizeof(float)); error = ex_get_all_times(exoid, time_values); printf("\nafter ex_get_all_times, error = %3d\n", error); printf("time values at all time steps are:\n"); for (i = 0; i < num_time_steps; i++) printf("%5.3f\n", time_values[i]); free(time_values); /* read all global variables at one time step */ var_values = (float *)calloc(num_glo_vars, sizeof(float)); error = ex_get_glob_vars(exoid, time_step, num_glo_vars, var_values); printf("\nafter ex_get_glob_vars, error = %3d\n", error); printf("global variable values at time step %2d\n", time_step); for (i = 0; i < num_glo_vars; i++) printf("%5.3f\n", var_values[i]); free(var_values); /* read a single global variable through time */ var_index = 1; beg_time = 1; end_time = -1; var_values = (float *)calloc(num_time_steps, sizeof(float)); error = ex_get_glob_var_time(exoid, var_index, beg_time, end_time, var_values); printf("\nafter ex_get_glob_var_time, error = %3d\n", error); printf("global variable %2d values through time:\n", var_index); for (i = 0; i < num_time_steps; i++) printf("%5.3f\n", var_values[i]); free(var_values); /* read a nodal variable at one time step */ if (num_nodes > 0) { var_values = (float *)calloc(num_nodes, sizeof(float)); error = ex_get_nodal_var(exoid, time_step, var_index, num_nodes, var_values); printf("\nafter ex_get_nodal_var, error = %3d\n", error); printf("nodal variable %2d values at time step %2d\n", var_index, time_step); for (i = 0; i < num_nodes; i++) printf("%5.3f\n", var_values[i]); free(var_values); /* read a nodal variable through time */ var_values = (float *)calloc(num_time_steps, sizeof(float)); node_num = 1; error = ex_get_nodal_var_time(exoid, var_index, node_num, beg_time, end_time, var_values); printf("\nafter ex_get_nodal_var_time, error = %3d\n", error); printf("nodal variable %2d values for node %2d through time:\n", var_index, node_num); for (i = 0; i < num_time_steps; i++) printf("%5.3f\n", var_values[i]); free(var_values); } /* read an element variable at one time step */ if (num_elem_blk > 0) { ids = (int *)calloc(num_elem_blk, sizeof(int)); error = ex_get_elem_blk_ids(exoid, ids); printf("\n after ex_get_elem_blk_ids, error = %3d\n", error); for (i = 0; i < num_elem_blk; i++) { if (num_elem_in_block[i] > 0) { var_values = (float *)calloc(num_elem_in_block[i], sizeof(float)); error = ex_get_elem_var(exoid, time_step, var_index, ids[i], num_elem_in_block[i], var_values); printf("\nafter ex_get_elem_var, error = %3d\n", error); if (!error) { printf("element variable %2d values of element block %2d at time step %2d\n", var_index, ids[i], time_step); for (j = 0; j < num_elem_in_block[i]; j++) printf("%5.3f\n", var_values[j]); } free(var_values); } } free(num_elem_in_block); free(ids); } /* read an element variable through time */ if (num_ele_vars > 0) { var_values = (float *)calloc(num_time_steps, sizeof(float)); var_index = 2; elem_num = 2; error = ex_get_elem_var_time(exoid, var_index, elem_num, beg_time, end_time, var_values); printf("\nafter ex_get_elem_var_time, error = %3d\n", error); printf("element variable %2d values for element %2d through time:\n", var_index, elem_num); for (i = 0; i < num_time_steps; i++) printf("%5.3f\n", var_values[i]); free(var_values); } /* read a sideset variable at one time step */ if (num_sset_vars > 0) { ids = (int *)calloc(num_side_sets, sizeof(int)); error = ex_get_side_set_ids(exoid, ids); printf("\n after ex_get_side_set_ids, error = %3d\n", error); for (i = 0; i < num_side_sets; i++) { var_values = (float *)calloc(num_elem_per_set[i], sizeof(float)); error = ex_get_sset_var(exoid, time_step, var_index, ids[i], num_elem_per_set[i], var_values); printf("\nafter ex_get_sset_var, error = %3d\n", error); if (!error) { printf("sideset variable %2d values of sideset %2d at time step %2d\n", var_index, ids[i], time_step); for (j = 0; j < num_elem_per_set[i]; j++) printf("%5.3f\n", var_values[j]); } free(var_values); } free(num_elem_per_set); free(ids); } /* read a nodeset variable at one time step */ if (num_nset_vars > 0) { ids = (int *)calloc(num_node_sets, sizeof(int)); error = ex_get_node_set_ids(exoid, ids); printf("\n after ex_get_node_set_ids, error = %3d\n", error); for (i = 0; i < num_node_sets; i++) { var_values = (float *)calloc(num_nodes_per_set[i], sizeof(float)); error = ex_get_nset_var(exoid, time_step, var_index, ids[i], num_nodes_per_set[i], var_values); printf("\nafter ex_get_nset_var, error = %3d\n", error); if (!error) { printf("nodeset variable %2d values of nodeset %2d at time step %2d\n", var_index, ids[i], time_step); for (j = 0; j < num_nodes_per_set[i]; j++) printf("%5.3f\n", var_values[j]); } free(var_values); } free(ids); } if (num_node_sets > 0) free(num_nodes_per_set); error = ex_close(exoid); printf("\nafter ex_close, error = %3d\n", error); return 0; }
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]; 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_cvt_nodes_to_sides",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_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) { sprintf(errmsg, "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) { sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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_elem_blk_ids(exoid, elem_blk_ids)) { sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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) ex_safe_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; sprintf(errmsg, "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_elem_conn( exoid, elem_blk_parms[p_ndx].elem_blk_id, connect) == -1) { sprintf(errmsg, "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) { sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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; sprintf(errmsg, "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: ex_safe_free(connect); ex_safe_free(ss_elem_node_ndx); ex_safe_free(ss_parm_ndx); ex_safe_free(elem_blk_parms); ex_safe_free(elem_blk_ids); ex_safe_free(ss_elem_ndx); ex_safe_free(same_elem_type); return (err_stat); }
int main(int argc, char **argv) { int exoid, exoid2, num_dim, num_nodes, num_elem, num_elem_blk; int num_elem_in_block, num_node_sets, num_nodes_per_elem, num_attr; int num_side_sets, error; int i, j; int *elem_map, *connect, *node_list, *node_ctr_list, *elem_list, *side_list; int *ids; int num_nodes_in_set, num_elem_in_set; int num_sides_in_set, num_df_in_set; int num_qa_rec, num_info; int CPU_word_size, IO_word_size; int num_props, prop_value, *prop_values; float *x, *y, *z; float *dist_fact; float version, fdum; float attrib[1]; char *coord_names[3], *qa_record[2][4], *info[3]; char title[MAX_LINE_LENGTH + 1], elem_type[MAX_STR_LENGTH + 1]; char *prop_names[3]; char *cdum = 0; /* Specify compute and i/o word size */ CPU_word_size = 0; /* sizeof(float) */ IO_word_size = 4; /* float */ /* open EXODUS II file for reading */ ex_opts(EX_VERBOSE | EX_ABORT); exoid = ex_open("test.exo", /* filename path */ EX_READ, /* access mode */ &CPU_word_size, /* CPU float word size in bytes */ &IO_word_size, /* I/O float word size in bytes */ &version); /* returned version number */ printf("after ex_open for test.exo\n"); printf(" cpu word size: %d io word size: %d\n", CPU_word_size, IO_word_size); /* create EXODUS II file for writing */ exoid2 = ex_create("test2.exo", /* filename path */ EX_CLOBBER, /* create mode */ &CPU_word_size, /* CPU float word size in bytes */ &IO_word_size); /* I/O float word size in bytes */ printf("after ex_create for test2.exo, exoid = %d\n", exoid2); /* read initialization parameters */ error = ex_get_init(exoid, title, &num_dim, &num_nodes, &num_elem, &num_elem_blk, &num_node_sets, &num_side_sets); printf("after ex_get_init, error = %d\n", error); /* write initialization parameters */ error = ex_put_init(exoid2, title, num_dim, num_nodes, num_elem, num_elem_blk, num_node_sets, num_side_sets); printf("after ex_put_init, error = %d\n", error); /* read nodal coordinate values */ x = (float *)calloc(num_nodes, sizeof(float)); y = (float *)calloc(num_nodes, sizeof(float)); if (num_dim >= 3) z = (float *)calloc(num_nodes, sizeof(float)); else z = 0; error = ex_get_coord(exoid, x, y, z); printf("\nafter ex_get_coord, error = %3d\n", error); /* write nodal coordinate values */ error = ex_put_coord(exoid2, x, y, z); printf("after ex_put_coord, error = %d\n", error); free(x); free(y); if (num_dim >= 3) free(z); /* read nodal coordinate names */ for (i = 0; i < num_dim; i++) { coord_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_coord_names(exoid, coord_names); printf("\nafter ex_get_coord_names, error = %3d\n", error); /* write nodal coordinate names */ error = ex_put_coord_names(exoid2, coord_names); printf("after ex_put_coord_names, error = %d\n", error); for (i = 0; i < num_dim; i++) { free(coord_names[i]); } /* read element order map */ elem_map = (int *)calloc(num_elem, sizeof(int)); error = ex_get_map(exoid, elem_map); printf("\nafter ex_get_map, error = %3d\n", error); /* write element order map */ error = ex_put_map(exoid2, elem_map); printf("after ex_put_map, error = %d\n", error); free(elem_map); /* read and write element block parameters and element connectivity */ ids = (int *)calloc(num_elem_blk, sizeof(int)); error = ex_get_elem_blk_ids(exoid, ids); printf("\nafter ex_get_elem_blk_ids, error = %3d\n", error); attrib[0] = 3.14159; for (i = 0; i < num_elem_blk; i++) { error = ex_get_elem_block(exoid, ids[i], elem_type, &num_elem_in_block, &num_nodes_per_elem, &num_attr); printf("\nafter ex_get_elem_block, error = %d\n", error); error = ex_put_elem_block(exoid2, ids[i], elem_type, num_elem_in_block, num_nodes_per_elem, num_attr); printf("after ex_put_elem_block, error = %d\n", error); connect = (int *)calloc((num_nodes_per_elem * num_elem_in_block), sizeof(int)); error = ex_get_elem_conn(exoid, ids[i], connect); printf("\nafter ex_get_elem_conn, error = %d\n", error); error = ex_put_elem_conn(exoid2, ids[i], connect); printf("after ex_put_elem_conn, error = %d\n", error); /* write element block attributes */ error = ex_put_attr(exoid2, EX_ELEM_BLOCK, ids[i], attrib); printf("after ex_put_elem_attr, error = %d\n", error); free(connect); } /* read and write element block properties */ error = ex_inquire(exoid, EX_INQ_EB_PROP, &num_props, &fdum, cdum); printf("\nafter ex_inquire, error = %d\n", error); for (i = 0; i < num_props; i++) { prop_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_prop_names(exoid, EX_ELEM_BLOCK, prop_names); printf("after ex_get_prop_names, error = %d\n", error); error = ex_put_prop_names(exoid2, EX_ELEM_BLOCK, num_props, prop_names); printf("after ex_put_prop_names, error = %d\n", error); for (i = 0; i < num_props; i++) { for (j = 0; j < num_elem_blk; j++) { error = ex_get_prop(exoid, EX_ELEM_BLOCK, ids[j], prop_names[i], &prop_value); printf("after ex_get_prop, error = %d\n", error); if (i > 0) { /* first property is the ID which is already stored */ error = ex_put_prop(exoid2, EX_ELEM_BLOCK, ids[j], prop_names[i], prop_value); printf("after ex_put_prop, error = %d\n", error); } } } for (i = 0; i < num_props; i++) free(prop_names[i]); free(ids); /* read and write individual node sets */ ids = (int *)calloc(num_node_sets, sizeof(int)); error = ex_get_node_set_ids(exoid, ids); printf("\nafter ex_get_node_set_ids, error = %3d\n", error); for (i = 0; i < num_node_sets; i++) { error = ex_get_node_set_param(exoid, ids[i], &num_nodes_in_set, &num_df_in_set); printf("\nafter ex_get_node_set_param, error = %3d\n", error); error = ex_put_node_set_param(exoid2, ids[i], num_nodes_in_set, num_df_in_set); printf("after ex_put_node_set_param, error = %d\n", error); node_list = (int *)calloc(num_nodes_in_set, sizeof(int)); dist_fact = (float *)calloc(num_nodes_in_set, sizeof(float)); error = ex_get_node_set(exoid, ids[i], node_list); printf("\nafter ex_get_node_set, error = %3d\n", error); error = ex_put_node_set(exoid2, ids[i], node_list); printf("after ex_put_node_set, error = %d\n", error); if (num_df_in_set > 0) { error = ex_get_node_set_dist_fact(exoid, ids[i], dist_fact); printf("\nafter ex_get_node_set_dist_fact, error = %3d\n", error); error = ex_put_node_set_dist_fact(exoid2, ids[i], dist_fact); printf("after ex_put_node_set, error = %d\n", error); } free(node_list); free(dist_fact); } free(ids); /* read node set properties */ error = ex_inquire(exoid, EX_INQ_NS_PROP, &num_props, &fdum, cdum); printf("\nafter ex_inquire, error = %d\n", error); for (i = 0; i < num_props; i++) { prop_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } prop_values = (int *)calloc(num_node_sets, sizeof(int)); error = ex_get_prop_names(exoid, EX_NODE_SET, prop_names); printf("after ex_get_prop_names, error = %d\n", error); error = ex_put_prop_names(exoid2, EX_NODE_SET, num_props, prop_names); printf("after ex_put_prop_names, error = %d\n", error); for (i = 0; i < num_props; i++) { error = ex_get_prop_array(exoid, EX_NODE_SET, prop_names[i], prop_values); printf("after ex_get_prop_array, error = %d\n", error); error = ex_put_prop_array(exoid2, EX_NODE_SET, prop_names[i], prop_values); printf("after ex_put_prop_array, error = %d\n", error); } for (i = 0; i < num_props; i++) free(prop_names[i]); free(prop_values); /* read and write individual side sets */ ids = (int *)calloc(num_side_sets, sizeof(int)); error = ex_get_side_set_ids(exoid, ids); printf("\nafter ex_get_side_set_ids, error = %3d\n", error); for (i = 0; i < num_side_sets; i++) { error = ex_get_side_set_param(exoid, ids[i], &num_sides_in_set, &num_df_in_set); printf("\nafter ex_get_side_set_param, error = %3d\n", error); error = ex_put_side_set_param(exoid2, ids[i], num_sides_in_set, num_df_in_set); printf("after ex_put_side_set_param, error = %d\n", error); /* Note: The # of elements is same as # of sides! */ num_elem_in_set = num_sides_in_set; elem_list = (int *)calloc(num_elem_in_set, sizeof(int)); side_list = (int *)calloc(num_sides_in_set, sizeof(int)); node_ctr_list = (int *)calloc(num_elem_in_set, sizeof(int)); node_list = (int *)calloc(num_elem_in_set * 21, sizeof(int)); dist_fact = (float *)calloc(num_df_in_set, sizeof(float)); error = ex_get_side_set(exoid, ids[i], elem_list, side_list); printf("\nafter ex_get_side_set, error = %3d\n", error); error = ex_put_side_set(exoid2, ids[i], elem_list, side_list); printf("after ex_put_side_set, error = %d\n", error); error = ex_get_side_set_node_list(exoid, ids[i], node_ctr_list, node_list); printf("\nafter ex_get_side_set_node_list, error = %3d\n", error); if (num_df_in_set > 0) { error = ex_get_side_set_dist_fact(exoid, ids[i], dist_fact); printf("\nafter ex_get_side_set_dist_fact, error = %3d\n", error); error = ex_put_side_set_dist_fact(exoid2, ids[i], dist_fact); printf("after ex_put_side_set_dist_fact, error = %d\n", error); } free(elem_list); free(side_list); free(node_ctr_list); free(node_list); free(dist_fact); } /* read side set properties */ error = ex_inquire(exoid, EX_INQ_SS_PROP, &num_props, &fdum, cdum); printf("\nafter ex_inquire, error = %d\n", error); for (i = 0; i < num_props; i++) { prop_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_prop_names(exoid, EX_SIDE_SET, prop_names); printf("after ex_get_prop_names, error = %d\n", error); for (i = 0; i < num_props; i++) { for (j = 0; j < num_side_sets; j++) { error = ex_get_prop(exoid, EX_SIDE_SET, ids[j], prop_names[i], &prop_value); printf("after ex_get_prop, error = %d\n", error); if (i > 0) { /* first property is ID so it is already stored */ error = ex_put_prop(exoid2, EX_SIDE_SET, ids[j], prop_names[i], prop_value); printf("after ex_put_prop, error = %d\n", error); } } } for (i = 0; i < num_props; i++) free(prop_names[i]); free(ids); /* read and write QA records */ ex_inquire(exoid, EX_INQ_QA, &num_qa_rec, &fdum, cdum); for (i = 0; i < num_qa_rec; i++) { for (j = 0; j < 4; j++) { qa_record[i][j] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } } error = ex_get_qa(exoid, qa_record); printf("\nafter ex_get_qa, error = %3d\n", error); error = ex_put_qa(exoid2, num_qa_rec, qa_record); printf("after ex_put_qa, error = %d\n", error); for (i = 0; i < num_qa_rec; i++) { for (j = 0; j < 4; j++) { free(qa_record[i][j]); } } /* read and write information records */ error = ex_inquire(exoid, EX_INQ_INFO, &num_info, &fdum, cdum); printf("\nafter ex_inquire, error = %3d\n", error); for (i = 0; i < num_info; i++) { info[i] = (char *)calloc((MAX_LINE_LENGTH + 1), sizeof(char)); } error = ex_get_info(exoid, info); printf("\nafter ex_get_info, error = %3d\n", error); error = ex_put_info(exoid2, num_info, info); printf("after ex_put_info, error = %d\n", error); for (i = 0; i < num_info; i++) { free(info[i]); } /* close the EXODUS files */ error = ex_close(exoid); printf("after ex_close, error = %d\n", error); error = ex_close(exoid2); printf("after ex_close (2), error = %d\n", error); return 0; }
static int read_elem_info(int pexoid, int Proc, PROB_INFO_PTR prob, MESH_INFO_PTR mesh) { /* Local declarations. */ char *yo = "read_elem_info"; int iblk, ielem, inode, lnode, cnode, iplace, len; int max_nsur = 0; int i; int *nmap, *emap, *connect; int **sur_elem, *nsurnd; ELEM_INFO_PTR elements = mesh->elements; double tmp0, tmp1, tmp2; float *xptr = NULL, *yptr = NULL, *zptr = NULL; /***************************** BEGIN EXECUTION ******************************/ DEBUG_TRACE_START(Proc, yo); /* allocate memory for the global number maps */ nmap = (int *) malloc ((mesh->num_nodes + mesh->num_elems) * sizeof(int)); if (!nmap) { Gen_Error(0, "fatal: insufficient memory"); return 0; } emap = nmap + mesh->num_nodes; /* * get the global maps */ if (ex_get_elem_num_map(pexoid, emap) < 0) { Gen_Error(0, "fatal: Error returned from ex_get_elem_num_map"); return 0; } if (ex_get_node_num_map(pexoid, nmap) < 0) { Gen_Error(0, "fatal: Error returned from ex_get_node_num_map"); return 0; } /* allocate memory for the coordinates */ xptr = (float *) malloc (mesh->num_dims * mesh->num_nodes * sizeof(float)); if (!xptr) { Gen_Error(0, "fatal: insufficient memory"); return 0; } switch (mesh->num_dims) { case 3: zptr = xptr + 2 * mesh->num_nodes; /* FALLTHRU */ case 2: yptr = xptr + mesh->num_nodes; } if (ex_get_coord(pexoid, xptr, yptr, zptr) < 0) { Gen_Error(0, "fatal: Error returned from ex_get_coord"); return 0; } /* * figure out which element block needs * the most space for its connect table */ len = 0; for (iblk = 0; iblk < mesh->num_el_blks; iblk++) if ((iplace = mesh->eb_cnts[iblk] * mesh->eb_nnodes[iblk]) > len) len = iplace; connect = (int *) malloc (len * sizeof(int)); if (!connect) { Gen_Error(0, "fatal: insufficient memory"); return 0; } /***************************************************************************/ /* Fill the Connect table, Coordinates, Global Ids for each element */ /***************************************************************************/ iplace = 0; for (iblk = 0; iblk < mesh->num_el_blks; iblk++) { if (mesh->eb_cnts[iblk] > 0) { if (ex_get_elem_conn(pexoid, mesh->eb_ids[iblk], connect) < 0) { Gen_Error(0, "fatal: Error returned from ex_get_elem_conn"); return 0; } cnode = 0; for (ielem = 0; ielem < mesh->eb_cnts[iblk]; ielem++) { /* set some fields in the element structure */ elements[iplace].border = 0; elements[iplace].globalID = emap[iplace]; elements[iplace].elem_blk = iblk; elements[iplace].my_part = Proc; elements[iplace].perm_value = -1; elements[iplace].invperm_value = -1; elements[iplace].nadj = 0; elements[iplace].adj_len = 0; /* first weights are all 1 for now */ elements[iplace].cpu_wgt[0] = 1.0; if (MAX_CPU_WGTS>1){ /* second weights will be set later */ elements[iplace].cpu_wgt[1] = 0.0; /* make artificial data for more multi-weights */ for (i = 2; i < MAX_CPU_WGTS; i++) elements[iplace].cpu_wgt[i] = elements[iplace].my_part + 0.5*((elements[iplace].globalID)%i); } elements[iplace].mem_wgt = 1.0; /* allocate space for the connect list and the coordinates */ elements[iplace].connect = (int *) malloc(mesh->eb_nnodes[iblk] * sizeof(int)); if (!(elements[iplace].connect)) { Gen_Error(0, "fatal: insufficient memory"); return 0; } elements[iplace].coord = (float **) malloc(mesh->eb_nnodes[iblk] * sizeof(float *)); if (!(elements[iplace].coord)) { Gen_Error(0, "fatal: insufficient memory"); return 0; } /* save the connect table as local numbers for the moment */ tmp0 = tmp1 = tmp2 = 0.; for (inode = 0; inode < mesh->eb_nnodes[iblk]; inode++) { lnode = connect[cnode] - 1; elements[iplace].connect[inode] = lnode; cnode++; elements[iplace].coord[inode] = (float *) calloc(mesh->num_dims, sizeof(float)); if (!(elements[iplace].coord[inode])) { Gen_Error(0, "fatal: insufficient memory"); return 0; } switch (mesh->num_dims) { case 3: elements[iplace].coord[inode][2] = zptr[lnode]; tmp2 += zptr[lnode]; /* FALLTHRU */ case 2: elements[iplace].coord[inode][1] = yptr[lnode]; tmp1 += yptr[lnode]; /* FALLTHRU */ case 1: elements[iplace].coord[inode][0] = xptr[lnode]; tmp0 += xptr[lnode]; } } /* End: "for (inode = 0; inode < mesh->eb_nnodes[iblk]; inode++)" */ elements[iplace].avg_coord[0] = tmp0 / mesh->eb_nnodes[iblk]; elements[iplace].avg_coord[1] = tmp1 / mesh->eb_nnodes[iblk]; elements[iplace].avg_coord[2] = tmp2 / mesh->eb_nnodes[iblk]; iplace++; } /* End: "for (ielem = 0; ielem < mesh->eb_cnts[iblk]; ielem++)" */ } /* End: "if (mesh->eb_cnts[iblk] > 0)" */ } /* End: "for (iblk = 0; iblk < mesh->num_el_blks; iblk++)" */ /* free some memory */ free(connect); free(xptr); /*************************************************************************/ /* Find the adjacency list for each element */ /* Part one: find the surrounding elements for each node */ /*************************************************************************/ sur_elem = (int **) malloc(mesh->num_nodes * sizeof(int *)); if (!sur_elem) { Gen_Error(0, "fatal: insufficient memory"); return 0; } nsurnd = (int *) malloc(mesh->num_nodes * sizeof(int)); if (!nsurnd) { Gen_Error(0, "fatal: insufficient memory"); return 0; } if (!find_surnd_elem(mesh, sur_elem, nsurnd, &max_nsur)) { Gen_Error(0, "fatal: Error returned from find_surnd_elems"); return 0; } /*************************************************************************/ /* Part two: Find the adjacencies on this processor */ /* and get the edge weights */ /*************************************************************************/ if (!find_adjacency(Proc, mesh, sur_elem, nsurnd, max_nsur)) { Gen_Error(0, "fatal: Error returned from find_adjacency"); return 0; } /* * convert the node numbers in the connect lists to Global IDs * since they will be much easier to work with */ for (ielem = 0; ielem < mesh->num_elems; ielem++) { iblk = elements[ielem].elem_blk; for (inode = 0; inode < mesh->eb_nnodes[iblk]; inode++) { elements[ielem].connect[inode] = nmap[elements[ielem].connect[inode]]; } } /* * let cpu_wgt[1] be the number of sides (surfaces) not * connected to other elements. (useful test case for multi-weight * load balancing). */ if (MAX_CPU_WGTS>1){ for (ielem = 0; ielem < mesh->num_elems; ielem++) { elements[ielem].cpu_wgt[1] = elements[ielem].adj_len - elements[ielem].nadj; /* EBEB Strangely, nadj is often one less than expected so subtract one from the wgt to compensate. */ if (elements[ielem].cpu_wgt[1] >= 1.0) elements[ielem].cpu_wgt[1] -= 1.0; } } for (inode = 0; inode < mesh->num_nodes; inode++) free(sur_elem[inode]); free(sur_elem); free(nsurnd); free(nmap); DEBUG_TRACE_END(Proc, yo); return 1; }
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, int side_set_id, int *side_set_node_cnt_list, int *side_set_node_list) { int i, j, m; int num_side_sets, num_elem_blks, num_df, ndim; int tot_num_elem = 0, tot_num_ss_elem = 0, elem_num = 0; int connect_offset, side_num, node_pos; int *elem_blk_ids, *connect; int *ss_elem_ndx, *ss_elem_node_ndx, *ss_parm_ndx; int *side_set_elem_list, *side_set_side_list; int elem_ctr, node_ctr, elem_num_pos; int num_elem_in_blk, num_nodes_per_elem, num_attr; float fdum; char *cdum, elem_type[MAX_STR_LENGTH+1]; struct elem_blk_parm { char elem_type[MAX_STR_LENGTH+1]; int elem_blk_id; int num_elem_in_blk; int num_nodes_per_elem; int num_nodes_per_side; int num_attr; int elem_ctr; int elem_type_val; } *elem_blk_parms; /* 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 */ cdum = 0; /* initialize even though it is not used */ /* first check if any side sets are specified */ /* inquire how many side sets have been stored */ if ((ex_inquire(exoid, EX_INQ_SIDE_SETS, &num_side_sets, &fdum, cdum)) == -1) { 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,VAR_SS_IDS,side_set_id); if (exerrval != 0) { if (exerrval == EX_NULLENTITY) { sprintf(errmsg, "Warning: side set %d is NULL in file id %d", side_set_id,exoid); ex_err("ex_get_side_set_node_list",errmsg,EX_MSG); return (EX_WARN); } else { sprintf(errmsg, "Error: failed to locate side set id %d 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); } } if ((ex_inquire(exoid, EX_INQ_ELEM_BLK, &num_elem_blks, &fdum, cdum)) == -1) { 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); } if ((ex_inquire(exoid, EX_INQ_ELEM, &tot_num_elem, &fdum, cdum)) == -1) { 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 */ if ((ex_inquire(exoid, EX_INQ_DIM, &ndim, &fdum, cdum)) == -1) { sprintf(errmsg, "Error: failed to get dimensionality in file id %d",exoid); ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval); return(EX_FATAL); } /* First determine the # of elements in the side set*/ if ((ex_get_side_set_param(exoid,side_set_id,&tot_num_ss_elem,&num_df)) == -1) { sprintf(errmsg, "Error: failed to get number of elements in side set %d 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=static_cast<int*>(malloc(tot_num_ss_elem*sizeof(int))))) { 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=static_cast<int*>(malloc(tot_num_ss_elem*sizeof(int))))) { 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",errmsg,exerrval); return (EX_FATAL); } if (ex_get_side_set(exoid, side_set_id, side_set_elem_list, side_set_side_list) == -1) { free(side_set_elem_list); free(side_set_side_list); sprintf(errmsg, "Error: failed to get side set %d 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= static_cast<int*>(malloc(tot_num_ss_elem*sizeof(int))))) { free(side_set_elem_list); 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",errmsg,exerrval); return (EX_FATAL); } /* Sort side set element list into index array - non-destructive */ 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 */ if (!(elem_blk_ids= static_cast<int*>(malloc(num_elem_blks*sizeof(int))))) { exerrval = EX_MEMFAIL; free(ss_elem_ndx); free(side_set_side_list); 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",errmsg,exerrval); return (EX_FATAL); } if (ex_get_elem_blk_ids(exoid, elem_blk_ids) == -1) { free(elem_blk_ids); free(ss_elem_ndx); free(side_set_side_list); 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",errmsg,EX_MSG); return(EX_FATAL); } /* Allocate space for the element block params */ if (!(elem_blk_parms= static_cast<struct elem_blk_parm*>(malloc(num_elem_blks*sizeof(struct elem_blk_parm))))) { free(elem_blk_ids); free(ss_elem_ndx); free(side_set_side_list); 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",errmsg,exerrval); return (EX_FATAL); } elem_ctr = 0; for (i=0; i<num_elem_blks; i++) { /* read in an element block parameter */ if ((ex_get_elem_block (exoid, elem_blk_ids[i], elem_type, &num_elem_in_blk, &num_nodes_per_elem, &num_attr)) == -1) { free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(side_set_side_list); free(side_set_elem_list); sprintf(errmsg, "Error: failed to get element block %d parameters in file id %d", elem_blk_ids[i], exoid); ex_err("ex_get_side_set_node_list",errmsg,EX_MSG); return(EX_FATAL); } elem_blk_parms[i].num_elem_in_blk = num_elem_in_blk; elem_blk_parms[i].num_nodes_per_elem = num_nodes_per_elem; elem_blk_parms[i].num_attr = num_attr; for (m=0; m < strlen(elem_type); m++) elem_blk_parms[i].elem_type[m] = toupper((int)elem_type[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 = CIRCLE; /* set side set node stride */ elem_blk_parms[i].num_nodes_per_side = 1; } else if (strncmp(elem_blk_parms[i].elem_type,"SPHERE",3) == 0) { elem_blk_parms[i].elem_type_val = SPHERE; /* set side set node stride */ elem_blk_parms[i].num_nodes_per_side = 1; } else if (strncmp(elem_blk_parms[i].elem_type,"QUAD",3) == 0) { elem_blk_parms[i].elem_type_val = QUAD; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 4) elem_blk_parms[i].num_nodes_per_side = 2; else if (elem_blk_parms[i].num_nodes_per_elem == 5) elem_blk_parms[i].num_nodes_per_side = 2; else elem_blk_parms[i].num_nodes_per_side = 3; } else if (strncmp(elem_blk_parms[i].elem_type,"TRIANGLE",3) == 0) { elem_blk_parms[i].elem_type_val = 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 = 2; else elem_blk_parms[i].num_nodes_per_side = 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 = 3; else elem_blk_parms[i].num_nodes_per_side = 6; } } else if (strncmp(elem_blk_parms[i].elem_type,"SHELL",3) == 0) { elem_blk_parms[i].elem_type_val = 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 = 2; else if (elem_blk_parms[i].num_nodes_per_elem == 4) elem_blk_parms[i].num_nodes_per_side = 4; else elem_blk_parms[i].num_nodes_per_side = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"HEX",3) == 0) { elem_blk_parms[i].elem_type_val = 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 = 4; else if (elem_blk_parms[i].num_nodes_per_elem == 9) /* 9-node bricks */ elem_blk_parms[i].num_nodes_per_side = 4; else if (elem_blk_parms[i].num_nodes_per_elem == 12) /* HEXSHELLS */ elem_blk_parms[i].num_nodes_per_side = 4; else if (elem_blk_parms[i].num_nodes_per_elem == 27) /* 27-node bricks */ elem_blk_parms[i].num_nodes_per_side = 9; else elem_blk_parms[i].num_nodes_per_side = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"TETRA",3) == 0) { elem_blk_parms[i].elem_type_val = TETRA; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 4) elem_blk_parms[i].num_nodes_per_side = 3; else if (elem_blk_parms[i].num_nodes_per_elem == 8) elem_blk_parms[i].num_nodes_per_side = 4; else elem_blk_parms[i].num_nodes_per_side = 6; } else if (strncmp(elem_blk_parms[i].elem_type,"WEDGE",3) == 0) { elem_blk_parms[i].elem_type_val = WEDGE; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 6) elem_blk_parms[i].num_nodes_per_side = 4; else elem_blk_parms[i].num_nodes_per_side = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"PYRAMID",3) == 0) { elem_blk_parms[i].elem_type_val = PYRAMID; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 5) elem_blk_parms[i].num_nodes_per_side = 4; else elem_blk_parms[i].num_nodes_per_side = 8; } else if (strncmp(elem_blk_parms[i].elem_type,"BEAM",3) == 0) { elem_blk_parms[i].elem_type_val = BEAM; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 2) elem_blk_parms[i].num_nodes_per_side = 2; else elem_blk_parms[i].num_nodes_per_side = 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 = TRUSS; /* determine side set node stride */ if (elem_blk_parms[i].num_nodes_per_elem == 2) elem_blk_parms[i].num_nodes_per_side = 2; else elem_blk_parms[i].num_nodes_per_side = 3; } else if (strncmp(elem_blk_parms[i].elem_type,"NULL",3) == 0) { elem_blk_parms[i].elem_type_val = '\0'; elem_blk_parms[i].num_nodes_per_side = 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 = UNK; elem_blk_parms[i].num_nodes_per_side = 0; } elem_blk_parms[i].elem_blk_id = elem_blk_ids[i]; /* 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=static_cast<int*>(malloc(tot_num_ss_elem*sizeof(int))))) { free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(side_set_side_list); free(side_set_elem_list); 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); return (EX_FATAL); } /* Allocate space for the ss element to node list index array */ if (!(ss_elem_node_ndx=static_cast<int*>(malloc(tot_num_ss_elem*sizeof(int))))) { free(ss_parm_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(side_set_side_list); free(side_set_elem_list); 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); return (EX_FATAL); } /* 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++) { for (j=0; j<num_elem_blks; j++) { if (elem_blk_parms[j].elem_type_val != '\0') if (side_set_elem_list[i] <= elem_blk_parms[j].elem_ctr) break; } if (j >= num_elem_blks) { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid element number %d found in side set %d in file %d", side_set_elem_list[i], side_set_id, exoid); free(ss_parm_ndx); free(ss_elem_node_ndx); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(side_set_side_list); free(side_set_elem_list); ex_err("ex_get_side_set_node_list",errmsg,EX_MSG); return (EX_FATAL); } ss_parm_ndx[i] = j; /* assign parameter block index */ 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 == WEDGE && (side_set_side_list[i] == 4 || side_set_side_list[i] == 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 == PYRAMID && (side_set_side_list[i] < 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 == SHELL && (side_set_side_list[i] > 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 == TRIANGLE && ndim == 3 && side_set_side_list[i] > 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; } /* All setup, ready to go ... */ elem_ctr=0; for (j=0; j < tot_num_ss_elem; j++) { if (side_set_elem_list[ss_elem_ndx[j]] > 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=static_cast<int*>(malloc(elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].num_elem_in_blk* elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].num_nodes_per_elem* (int)sizeof(int))))) { free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(ss_elem_node_ndx); free(ss_parm_ndx); free(side_set_side_list); free(side_set_elem_list); 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); return (EX_FATAL); } /* get connectivity array */ if (ex_get_elem_conn( exoid, elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id, connect) == -1) { free(connect); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(ss_elem_node_ndx); free(ss_parm_ndx); free(side_set_side_list); free(side_set_elem_list); 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); return (EX_FATAL); } elem_ctr = elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_ctr; } /* For each side in side set, use the appropriate lookup table to determine the nodes from the connect array. */ elem_num = side_set_elem_list[ss_elem_ndx[j]]-1;/* element number 0-based*/ /* calculate the relative element number position in it's block*/ elem_num_pos = elem_num - (elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_ctr - elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].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[ss_parm_ndx[ss_elem_ndx[j]]].num_nodes_per_elem; node_pos = ss_elem_node_ndx[ss_elem_ndx[j]]; connect_offset = num_nodes_per_elem*elem_num_pos; side_num = side_set_side_list[ss_elem_ndx[j]]-1; switch (elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_type_val) { case CIRCLE: case SPHERE: { /* Note: no side-node lookup table is used for this simple case */ side_set_node_list[node_pos] = connect[connect_offset]; side_set_node_cnt_list[ss_elem_ndx[j]] = 1; /* 1 node object */ break; } case TRUSS: case BEAM: { /* Note: no side-node lookup table is used for this simple case */ side_set_node_list[node_pos] = connect[connect_offset]; side_set_node_list[node_pos+1] = connect[connect_offset+1]; side_set_node_cnt_list[ss_elem_ndx[j]] = 2; /* 2 node object */ if (num_nodes_per_elem > 2) { side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */ side_set_node_list[node_pos+2] = connect[connect_offset+2]; } break; } case TRIANGLE: { if (side_num+1 < 1 || side_num+1 > 5) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid triangle edge number %d in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); free(connect); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(ss_elem_node_ndx); free(ss_parm_ndx); free(side_set_side_list); free(side_set_elem_list); return(EX_FATAL); } if (ndim == 2) /* 2d TRIs */ { side_set_node_list[node_pos] = connect[connect_offset+tri_table[side_num][0]-1]; side_set_node_list[node_pos+1] = connect[connect_offset+tri_table[side_num][1]-1]; side_set_node_cnt_list[ss_elem_ndx[j]] = 2; /* 2 node object */ if (num_nodes_per_elem > 3) /* 6-node TRI */ { side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */ side_set_node_list[node_pos+2] = connect[connect_offset+tri_table[side_num][2]-1]; } } else if (ndim == 3) /* 3d TRIs */ { side_set_node_list[node_pos] = connect[connect_offset+tri3_table[side_num][0]-1]; side_set_node_list[node_pos+1] = connect[connect_offset+tri3_table[side_num][1]-1]; side_set_node_cnt_list[ss_elem_ndx[j]] = 2; /* 2 node object */ if (side_num+1 <= 2) /* 3- or 6-node face */ { if (num_nodes_per_elem == 3) /* 3-node face */ { side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */ side_set_node_list[node_pos+2] = connect[connect_offset+tri3_table[side_num][2]-1]; } else /* 6-node face */ { side_set_node_cnt_list[ss_elem_ndx[j]] = 6; /* 6 node object */ side_set_node_list[node_pos+2] = connect[connect_offset+tri3_table[side_num][2]-1]; side_set_node_list[node_pos+3] = connect[connect_offset+tri3_table[side_num][3]-1]; side_set_node_list[node_pos+4] = connect[connect_offset+tri3_table[side_num][4]-1]; 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 */ { side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */ side_set_node_list[node_pos+2] = connect[connect_offset+tri3_table[side_num][2]-1]; } } } break; } case QUAD: { if (side_num+1 < 1 || side_num+1 > 4) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid quad edge number %d in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); free(connect); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(ss_elem_node_ndx); free(ss_parm_ndx); free(side_set_side_list); free(side_set_elem_list); return(EX_FATAL); } side_set_node_list[node_pos] = connect[connect_offset+quad_table[side_num][0]-1]; side_set_node_list[node_pos+1] = connect[connect_offset+quad_table[side_num][1]-1]; side_set_node_cnt_list[ss_elem_ndx[j]] = 2; /* 2 node object */ if (num_nodes_per_elem > 5) { side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */ side_set_node_list[node_pos+2] = connect[connect_offset+quad_table[side_num][2]-1]; } break; } case SHELL: { if (side_num+1 < 1 || side_num+1 > 6) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid shell face number %d in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); free(connect); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(ss_elem_node_ndx); free(ss_parm_ndx); free(side_set_side_list); free(side_set_elem_list); return(EX_FATAL); } side_set_node_list[node_pos] = connect[connect_offset+shell_table[side_num][0]-1]; side_set_node_list[node_pos+1] = connect[connect_offset+shell_table[side_num][1]-1]; side_set_node_cnt_list[ss_elem_ndx[j]] = 2; /* 2 node object */ if (num_nodes_per_elem > 2) /*** KLUDGE for 2D shells ***/ { if (side_num+1 <= 2) /* 4-node face */ { side_set_node_cnt_list[ss_elem_ndx[j]] = 4; /* 4 node object */ side_set_node_list[node_pos+2] = connect[connect_offset+shell_table[side_num][2]-1]; 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 */ { side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node object */ side_set_node_list[node_pos+4] = connect[connect_offset+shell_table[side_num][4]-1]; side_set_node_list[node_pos+5] = connect[connect_offset+shell_table[side_num][5]-1]; side_set_node_list[node_pos+6] = connect[connect_offset+shell_table[side_num][6]-1]; side_set_node_list[node_pos+7] = connect[connect_offset+shell_table[side_num][7]-1]; } else { side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node edge */ side_set_node_list[node_pos+2] = connect[connect_offset+shell_table[side_num][2]-1]; } } break; } case TETRA: { if (side_num+1 < 1 || side_num+1 > 4) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid tetra face number %d in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); free(connect); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(ss_elem_node_ndx); free(ss_parm_ndx); free(side_set_side_list); free(side_set_elem_list); return(EX_FATAL); } side_set_node_list[node_pos] = connect[connect_offset+tetra_table[side_num][0]-1]; side_set_node_list[node_pos+1] = connect[connect_offset+tetra_table[side_num][1]-1]; side_set_node_list[node_pos+2] = connect[connect_offset+tetra_table[side_num][2]-1]; side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node object */ if (num_nodes_per_elem == 8) { side_set_node_cnt_list[ss_elem_ndx[j]] = 4; /* 4 node object */ side_set_node_list[node_pos+3] = connect[connect_offset+tetra_table[side_num][3]-1]; } else if (num_nodes_per_elem > 8) { side_set_node_cnt_list[ss_elem_ndx[j]] = 6; /* 6 node object */ side_set_node_list[node_pos+3] = connect[connect_offset+tetra_table[side_num][3]-1]; side_set_node_list[node_pos+4] = connect[connect_offset+tetra_table[side_num][4]-1]; side_set_node_list[node_pos+5] = connect[connect_offset+tetra_table[side_num][5]-1]; } break; } case WEDGE: { if (side_num+1 < 1 || side_num+1 > 5) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid wedge face number %d in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); free(connect); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(ss_elem_node_ndx); free(ss_parm_ndx); free(side_set_side_list); free(side_set_elem_list); return(EX_FATAL); } side_set_node_list[node_pos++] = connect[connect_offset+wedge_table[side_num][0]-1]; side_set_node_list[node_pos++] = connect[connect_offset+wedge_table[side_num][1]-1]; side_set_node_list[node_pos++] = connect[connect_offset+wedge_table[side_num][2]-1]; if (wedge_table[side_num][3] == 0) { /* degenerate side? */ side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node side */ } else { side_set_node_list[node_pos++] = connect[connect_offset+wedge_table[side_num][3]-1]; side_set_node_cnt_list[ss_elem_ndx[j]] = 4; /* 4 node side */ } if (num_nodes_per_elem > 6) { side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node object */ side_set_node_list[node_pos++] = connect[connect_offset+wedge_table[side_num][4]-1]; side_set_node_list[node_pos++] = connect[connect_offset+wedge_table[side_num][5]-1]; side_set_node_list[node_pos++] = connect[connect_offset+wedge_table[side_num][6]-1]; if (wedge_table[side_num][7] == 0) /* degenerate side? */ side_set_node_cnt_list[ss_elem_ndx[j]] = 6; /* 6 node side */ else { side_set_node_list[node_pos++] = connect[connect_offset+wedge_table[side_num][7]-1]; side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node side */ } } break; } case PYRAMID: { if (side_num+1 < 1 || side_num+1 > 5) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid pyramid face number %d in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); free(connect); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(ss_elem_node_ndx); free(ss_parm_ndx); free(side_set_side_list); free(side_set_elem_list); return(EX_FATAL); } side_set_node_list[node_pos++] = connect[connect_offset+pyramid_table[side_num][0]-1]; side_set_node_list[node_pos++] = connect[connect_offset+pyramid_table[side_num][1]-1]; side_set_node_list[node_pos++] = connect[connect_offset+pyramid_table[side_num][2]-1]; if (pyramid_table[side_num][3] == 0) { /* degenerate side? */ side_set_node_cnt_list[ss_elem_ndx[j]] = 3; /* 3 node side */ } else { side_set_node_list[node_pos++] = connect[connect_offset+pyramid_table[side_num][3]-1]; side_set_node_cnt_list[ss_elem_ndx[j]] = 4; /* 4 node side */ } if (num_nodes_per_elem > 5) { side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node object */ side_set_node_list[node_pos++] = connect[connect_offset+pyramid_table[side_num][4]-1]; side_set_node_list[node_pos++] = connect[connect_offset+pyramid_table[side_num][5]-1]; side_set_node_list[node_pos++] = connect[connect_offset+pyramid_table[side_num][6]-1]; if (pyramid_table[side_num][7] == 0) /* degenerate side? */ side_set_node_cnt_list[ss_elem_ndx[j]] = 6; /* 6 node side */ else { side_set_node_list[node_pos++] = connect[connect_offset+pyramid_table[side_num][7]-1]; side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node side */ } } break; } case HEX: { if (side_num+1 < 1 || side_num+1 > 6) /* side number range check */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: Invalid hex face number %d in file id %d", side_num+1, exoid); ex_err("ex_get_side_set_node_list",errmsg,exerrval); free(connect); free(elem_blk_parms); free(elem_blk_ids); free(ss_elem_ndx); free(ss_elem_node_ndx); free(ss_parm_ndx); free(side_set_side_list); free(side_set_elem_list); return(EX_FATAL); } side_set_node_list[node_pos] = connect[connect_offset+hex_table[side_num][0]-1]; side_set_node_list[node_pos+1] = connect[connect_offset+hex_table[side_num][1]-1]; side_set_node_list[node_pos+2] = connect[connect_offset+hex_table[side_num][2]-1]; side_set_node_list[node_pos+3] = connect[connect_offset+hex_table[side_num][3]-1]; side_set_node_cnt_list[ss_elem_ndx[j]] = 4; /* 4 node object */ if (num_nodes_per_elem > 12) /* more nodes than HEXSHELL */ { side_set_node_cnt_list[ss_elem_ndx[j]] = 8; /* 8 node object */ side_set_node_list[node_pos+4] = connect[connect_offset+hex_table[side_num][4]-1]; side_set_node_list[node_pos+5] = connect[connect_offset+hex_table[side_num][5]-1]; side_set_node_list[node_pos+6] = connect[connect_offset+hex_table[side_num][6]-1]; 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 */ { side_set_node_cnt_list[ss_elem_ndx[j]] = 9; /* 9 node object */ 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[ss_parm_ndx[ss_elem_ndx[j]]].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 */ 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(EX_NOERR); }
//---------------------------------------------------------------------------- // // Modifications: // Kathleen Bonnell, Mon Oct 29 15:27:41 PST 2001 // Use vtkIdType for outPtCount to match VTK 4.0 API for retrieving the // number of Nodes. // // Brad Whitlock, Mon Nov 14 14:25:23 PST 2005 // Added SHELL4 element. // //---------------------------------------------------------------------------- void vtkExodusReader::ReadCells(int exoid) { int i, j, k; int num_elem_in_block; int num_nodes_per_elem; int num_attr; char elem_type[MAX_STR_LENGTH+1]; char all_caps_elem_type[MAX_STR_LENGTH+1]; int *connect, *pConnect; vtkUnstructuredGrid *output = this->GetOutput(); vtkIdList *cellIds=vtkIdList::New(); int cellType; int cellNumPoints; int *pointMapInOutArray; int inId, outId, *pId; vtkIdType outPtCount; int len; // I think we can do better than this. output->Allocate(this->NumberOfElements); // Set up the point maps. // Remember which points we have used. outPtCount = 0; pointMapInOutArray = new int[this->NumberOfNodes]; pId = pointMapInOutArray; if (this->StartBlock > 0 || this->EndBlock < this->NumberOfBlocks-1) { // Initialize to use none of them. for (inId = 0; inId < this->NumberOfNodes; ++inId) { *pId++ = -1; } } else { // Since we are reading the full data set, then preset the maps // to avoid shuffleing the points. outPtCount = this->NumberOfNodes; this->PointMapOutIn->SetNumberOfIds(this->NumberOfNodes); for (inId = 0; inId < this->NumberOfNodes; ++inId) { *pId++ = inId; this->PointMapOutIn->SetId(inId, inId); } } // Although information already read these ids ... //this->BlockIds->Reset(); //this->BlockIds->SetNumberOfValues(this->NumberOfBlocks); //ids = this->BlockIds->GetPointer((const int)(0)); //error = ex_get_elem_blk_ids (exoid, ids); // Initialize using the type of cells. // A block contains contains only one type of cell. for (i = this->StartBlock; i <= this->EndBlock; ++i) { // Although we read most of this information in ExecuteInformation, // we did not save the element types for the blocks. ex_get_elem_block(exoid, this->BlockIds->GetValue(i), elem_type, &num_elem_in_block, &num_nodes_per_elem, &num_attr); if (num_elem_in_block == 0) { continue; } connect = new int [num_nodes_per_elem*num_elem_in_block]; ex_get_elem_conn (exoid, this->BlockIds->GetValue(i), connect); // cellNumPoints may be smaller than num_nodes_per_elem // because of higher order cells. len = strlen(elem_type); for (j = 0 ; j < len ; j++) { all_caps_elem_type[j] = toupper(elem_type[j]); } if (strncmp(all_caps_elem_type, "HEX", 3) == 0) { cellType = VTK_HEXAHEDRON; cellNumPoints = 8; } else if (strncmp(all_caps_elem_type, "QUA", 3) == 0 || strncmp(all_caps_elem_type, "SHELL4", 6) == 0) { cellType = VTK_QUAD; cellNumPoints = 4; } else if (strncmp(all_caps_elem_type,"SPH",3)==0 || strncmp(all_caps_elem_type,"CIR",3)==0) { cellType = VTK_VERTEX; cellNumPoints = 1; } else if (strncmp(all_caps_elem_type, "TRU", 3) == 0) { cellType = VTK_LINE; cellNumPoints = 2; } else if (strncmp(all_caps_elem_type, "TRI", 3) == 0) { cellType = VTK_TRIANGLE; cellNumPoints = 3; } else if (strncmp(all_caps_elem_type, "TET", 3) == 0) { cellType = VTK_TETRA; cellNumPoints = 4; } else if (strncmp(all_caps_elem_type, "WED", 3) == 0) { cellType = VTK_WEDGE; cellNumPoints = 6; } else { vtkErrorMacro("Cannot handle type: " << elem_type << " with " << num_nodes_per_elem << " nodes."); delete [] connect; continue; } // Now save the cells in a cell array. pConnect = connect; for (j = 0; j < num_elem_in_block; ++j) { cellIds->Reset(); for (k = 0; k < cellNumPoints; ++k) { // Translate inId to outId and build up point map. inId = pConnect[k]-1; // Exodus stores ids starting form 1 not 0. outId = pointMapInOutArray[inId]; if (outId == -1) { // We have not seen this point before. outId = pointMapInOutArray[inId] = outPtCount++; this->PointMapOutIn->InsertId(outId, inId); } // Build up a list of cell pt ids to insert in to the output data set. cellIds->InsertNextId(outId); } // Skip to next element (may skip more than 8 nodes). pConnect += num_nodes_per_elem; // Insert cell into output. output->InsertNextCell(cellType, cellIds); } delete [] connect; connect = NULL; } // From now on we only need the OutIn map. delete [] pointMapInOutArray; pointMapInOutArray = NULL; cellIds->Delete(); cellIds = NULL; }
/*@ DMPlexCreateExodus - Create a DMPlex mesh from an ExodusII file ID. Collective on comm Input Parameters: + comm - The MPI communicator . exoid - The ExodusII id associated with a exodus file and obtained using ex_open - interpolate - Create faces and edges in the mesh Output Parameter: . dm - The DM object representing the mesh Level: beginner .keywords: mesh,ExodusII .seealso: DMPLEX, DMCreate() @*/ PetscErrorCode DMPlexCreateExodus(MPI_Comm comm, PetscInt exoid, PetscBool interpolate, DM *dm) { #if defined(PETSC_HAVE_EXODUSII) PetscMPIInt num_proc, rank; PetscSection coordSection; Vec coordinates; PetscScalar *coords; PetscInt coordSize, v; PetscErrorCode ierr; /* Read from ex_get_init() */ char title[PETSC_MAX_PATH_LEN+1]; int dim = 0, numVertices = 0, numCells = 0; int num_cs = 0, num_vs = 0, num_fs = 0; #endif PetscFunctionBegin; #if defined(PETSC_HAVE_EXODUSII) ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &num_proc);CHKERRQ(ierr); ierr = DMCreate(comm, dm);CHKERRQ(ierr); ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); /* Open EXODUS II file and read basic informations on rank 0, then broadcast to all processors */ if (!rank) { ierr = PetscMemzero(title,(PETSC_MAX_PATH_LEN+1)*sizeof(char));CHKERRQ(ierr); ierr = ex_get_init(exoid, title, &dim, &numVertices, &numCells, &num_cs, &num_vs, &num_fs); if (ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ExodusII ex_get_init() failed with error code %D\n",ierr); if (!num_cs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Exodus file does not contain any cell set\n"); } ierr = MPI_Bcast(title, PETSC_MAX_PATH_LEN+1, MPI_CHAR, 0, comm);CHKERRQ(ierr); ierr = MPI_Bcast(&dim, 1, MPI_INT, 0, comm);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) *dm, title);CHKERRQ(ierr); ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); ierr = DMPlexSetChart(*dm, 0, numCells+numVertices);CHKERRQ(ierr); /* Read cell sets information */ if (!rank) { PetscInt *cone; int c, cs, c_loc, v, v_loc; /* Read from ex_get_elem_blk_ids() */ int *cs_id; /* Read from ex_get_elem_block() */ char buffer[PETSC_MAX_PATH_LEN+1]; int num_cell_in_set, num_vertex_per_cell, num_attr; /* Read from ex_get_elem_conn() */ int *cs_connect; /* Get cell sets IDs */ ierr = PetscMalloc1(num_cs, &cs_id);CHKERRQ(ierr); ierr = ex_get_elem_blk_ids(exoid, cs_id);CHKERRQ(ierr); /* Read the cell set connectivity table and build mesh topology EXO standard requires that cells in cell sets be numbered sequentially and be pairwise disjoint. */ /* First set sizes */ for (cs = 0, c = 0; cs < num_cs; cs++) { ierr = ex_get_elem_block(exoid, cs_id[cs], buffer, &num_cell_in_set, &num_vertex_per_cell, &num_attr);CHKERRQ(ierr); for (c_loc = 0; c_loc < num_cell_in_set; ++c_loc, ++c) { ierr = DMPlexSetConeSize(*dm, c, num_vertex_per_cell);CHKERRQ(ierr); } } ierr = DMSetUp(*dm);CHKERRQ(ierr); for (cs = 0, c = 0; cs < num_cs; cs++) { ierr = ex_get_elem_block(exoid, cs_id[cs], buffer, &num_cell_in_set, &num_vertex_per_cell, &num_attr);CHKERRQ(ierr); ierr = PetscMalloc2(num_vertex_per_cell*num_cell_in_set,&cs_connect,num_vertex_per_cell,&cone);CHKERRQ(ierr); ierr = ex_get_elem_conn(exoid, cs_id[cs], cs_connect);CHKERRQ(ierr); /* EXO uses Fortran-based indexing, sieve uses C-style and numbers cell first then vertices. */ for (c_loc = 0, v = 0; c_loc < num_cell_in_set; ++c_loc, ++c) { for (v_loc = 0; v_loc < num_vertex_per_cell; ++v_loc, ++v) { cone[v_loc] = cs_connect[v]+numCells-1; } if (dim == 3) { /* Tetrahedra are inverted */ if (num_vertex_per_cell == 4) { PetscInt tmp = cone[0]; cone[0] = cone[1]; cone[1] = tmp; } /* Hexahedra are inverted */ if (num_vertex_per_cell == 8) { PetscInt tmp = cone[1]; cone[1] = cone[3]; cone[3] = tmp; } } ierr = DMPlexSetCone(*dm, c, cone);CHKERRQ(ierr); ierr = DMSetLabelValue(*dm, "Cell Sets", c, cs_id[cs]);CHKERRQ(ierr); } ierr = PetscFree2(cs_connect,cone);CHKERRQ(ierr); } ierr = PetscFree(cs_id);CHKERRQ(ierr); } ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); ierr = DMPlexStratify(*dm);CHKERRQ(ierr); if (interpolate) { DM idm = NULL; ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); /* Maintain Cell Sets label */ { DMLabel label; ierr = DMRemoveLabel(*dm, "Cell Sets", &label);CHKERRQ(ierr); if (label) {ierr = DMAddLabel(idm, label);CHKERRQ(ierr);} } ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = idm; } /* Create vertex set label */ if (!rank && (num_vs > 0)) { int vs, v; /* Read from ex_get_node_set_ids() */ int *vs_id; /* Read from ex_get_node_set_param() */ int num_vertex_in_set, num_attr; /* Read from ex_get_node_set() */ int *vs_vertex_list; /* Get vertex set ids */ ierr = PetscMalloc1(num_vs, &vs_id);CHKERRQ(ierr); ierr = ex_get_node_set_ids(exoid, vs_id);CHKERRQ(ierr); for (vs = 0; vs < num_vs; ++vs) { ierr = ex_get_node_set_param(exoid, vs_id[vs], &num_vertex_in_set, &num_attr);CHKERRQ(ierr); ierr = PetscMalloc1(num_vertex_in_set, &vs_vertex_list);CHKERRQ(ierr); ierr = ex_get_node_set(exoid, vs_id[vs], vs_vertex_list);CHKERRQ(ierr); for (v = 0; v < num_vertex_in_set; ++v) { ierr = DMSetLabelValue(*dm, "Vertex Sets", vs_vertex_list[v]+numCells-1, vs_id[vs]);CHKERRQ(ierr); } ierr = PetscFree(vs_vertex_list);CHKERRQ(ierr); } ierr = PetscFree(vs_id);CHKERRQ(ierr); } /* Read coordinates */ ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); ierr = PetscSectionSetChart(coordSection, numCells, numCells + numVertices);CHKERRQ(ierr); for (v = numCells; v < numCells+numVertices; ++v) { ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); } ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetBlockSize(coordinates, dim);CHKERRQ(ierr); ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); if (!rank) { float *x, *y, *z; ierr = PetscMalloc3(numVertices,&x,numVertices,&y,numVertices,&z);CHKERRQ(ierr); ierr = ex_get_coord(exoid, x, y, z);CHKERRQ(ierr); if (dim > 0) { for (v = 0; v < numVertices; ++v) coords[v*dim+0] = x[v]; } if (dim > 1) { for (v = 0; v < numVertices; ++v) coords[v*dim+1] = y[v]; } if (dim > 2) { for (v = 0; v < numVertices; ++v) coords[v*dim+2] = z[v]; } ierr = PetscFree3(x,y,z);CHKERRQ(ierr); } ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); ierr = DMSetCoordinatesLocal(*dm, coordinates);CHKERRQ(ierr); ierr = VecDestroy(&coordinates);CHKERRQ(ierr); /* Create side set label */ if (!rank && interpolate && (num_fs > 0)) { int fs, f, voff; /* Read from ex_get_side_set_ids() */ int *fs_id; /* Read from ex_get_side_set_param() */ int num_side_in_set, num_dist_fact_in_set; /* Read from ex_get_side_set_node_list() */ int *fs_vertex_count_list, *fs_vertex_list; /* Get side set ids */ ierr = PetscMalloc1(num_fs, &fs_id);CHKERRQ(ierr); ierr = ex_get_side_set_ids(exoid, fs_id);CHKERRQ(ierr); for (fs = 0; fs < num_fs; ++fs) { ierr = ex_get_side_set_param(exoid, fs_id[fs], &num_side_in_set, &num_dist_fact_in_set);CHKERRQ(ierr); ierr = PetscMalloc2(num_side_in_set,&fs_vertex_count_list,num_side_in_set*4,&fs_vertex_list);CHKERRQ(ierr); ierr = ex_get_side_set_node_list(exoid, fs_id[fs], fs_vertex_count_list, fs_vertex_list);CHKERRQ(ierr); for (f = 0, voff = 0; f < num_side_in_set; ++f) { const PetscInt *faces = NULL; PetscInt faceSize = fs_vertex_count_list[f], numFaces; PetscInt faceVertices[4], v; if (faceSize > 4) SETERRQ1(comm, PETSC_ERR_ARG_WRONG, "ExodusII side cannot have %d > 4 vertices", faceSize); for (v = 0; v < faceSize; ++v, ++voff) { faceVertices[v] = fs_vertex_list[voff]+numCells-1; } ierr = DMPlexGetFullJoin(*dm, faceSize, faceVertices, &numFaces, &faces);CHKERRQ(ierr); if (numFaces != 1) SETERRQ3(comm, PETSC_ERR_ARG_WRONG, "Invalid ExodusII side %d in set %d maps to %d faces", f, fs, numFaces); ierr = DMSetLabelValue(*dm, "Face Sets", faces[0], fs_id[fs]);CHKERRQ(ierr); ierr = DMPlexRestoreJoin(*dm, faceSize, faceVertices, &numFaces, &faces);CHKERRQ(ierr); } ierr = PetscFree2(fs_vertex_count_list,fs_vertex_list);CHKERRQ(ierr); } ierr = PetscFree(fs_id);CHKERRQ(ierr); } #else SETERRQ(comm, PETSC_ERR_SUP, "This method requires ExodusII support. Reconfigure using --download-exodusii"); #endif PetscFunctionReturn(0); }
int main(int argc, char **argv) { int exoid, num_dim, num_nodes, num_elem_blk; int *num_elem_in_block, *num_face_in_block, *num_nodes_per_elem, *num_edges_per_elem, *num_faces_per_elem, *num_attr; int error, nnodes; int i, j, k; int *connect, *fconnect; int *ids, *nnpe, *nnpf; int num_qa_rec, num_info; int CPU_word_size, IO_word_size; int idum; float *x, *y, *z; float version, fdum; char *coord_names[3], *qa_record[2][4], *info[3]; char *block_names[10]; char *elem_type[10]; char name[MAX_STR_LENGTH + 1]; char *cdum = 0; CPU_word_size = 0; /* sizeof(float) */ IO_word_size = 0; /* use what is stored in file */ ex_opts(EX_VERBOSE | EX_ABORT); /* open EXODUS II files */ exoid = ex_open("test-nfaced.exo", /* filename path */ EX_READ, /* access mode = READ */ &CPU_word_size, /* CPU word size */ &IO_word_size, /* IO word size */ &version); /* ExodusII library version */ printf("\nafter ex_open\n"); if (exoid < 0) exit(1); printf("test.exo is an EXODUSII file; version %4.2f\n", version); printf(" I/O word size %1d\n", IO_word_size); ex_inquire(exoid, EX_INQ_LIB_VERS, &idum, &version, cdum); printf("EXODUSII Library API; version %4.2f (%d)\n", version, idum); /* read database parameters */ { ex_init_params par; error = ex_get_init_ext(exoid, &par); printf("after ex_get_init, error = %3d\n", error); printf("database parameters:\n"); printf("title = '%s'\n", par.title); printf("num_dim = %" PRId64 "\n", par.num_dim); printf("num_nodes = %" PRId64 "\n", par.num_nodes); printf("num_edge = %" PRId64 "\n", par.num_edge); printf("num_face = %" PRId64 "\n", par.num_face); printf("num_elem = %" PRId64 "\n", par.num_elem); printf("num_elem_blk = %" PRId64 "\n", par.num_elem_blk); printf("num_node_sets = %" PRId64 "\n", par.num_node_sets); printf("num_side_sets = %" PRId64 "\n", par.num_side_sets); num_dim = par.num_dim; num_nodes = par.num_nodes; num_elem_blk = par.num_elem_blk; } assert(num_dim == 3); /* read nodal coordinates values and names from database */ x = (float *)calloc(num_nodes, sizeof(float)); y = (float *)calloc(num_nodes, sizeof(float)); z = (float *)calloc(num_nodes, sizeof(float)); error = ex_get_coord(exoid, x, y, z); printf("\nafter ex_get_coord, error = %3d\n", error); printf("x, y, z coords = \n"); for (i = 0; i < num_nodes; i++) { printf("%5.1f\t%5.1f\t%5.1f\n", x[i], y[i], z[i]); } free(x); free(y); free(z); for (i = 0; i < num_dim; i++) { coord_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_coord_names(exoid, coord_names); printf("\nafter ex_get_coord_names, error = %3d\n", error); printf("x coord name = '%s'\n", coord_names[0]); printf("y coord name = '%s'\n", coord_names[1]); printf("z coord name = '%s'\n", coord_names[2]); for (i = 0; i < num_dim; i++) free(coord_names[i]); /* read element block parameters */ if (num_elem_blk > 0) { ids = (int *)calloc(num_elem_blk, sizeof(int)); num_elem_in_block = (int *)calloc(num_elem_blk, sizeof(int)); num_face_in_block = (int *)calloc(num_elem_blk, sizeof(int)); num_nodes_per_elem = (int *)calloc(num_elem_blk, sizeof(int)); num_edges_per_elem = (int *)calloc(num_elem_blk, sizeof(int)); num_faces_per_elem = (int *)calloc(num_elem_blk, sizeof(int)); num_attr = (int *)calloc(num_elem_blk, sizeof(int)); for (i = 0; i < num_elem_blk; i++) { elem_type[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); block_names[i] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } error = ex_get_elem_blk_ids(exoid, ids); printf("\nafter ex_get_elem_blk_ids, error = %3d\n", error); error = ex_get_names(exoid, EX_ELEM_BLOCK, block_names); printf("\nafter ex_get_names, error = %3d\n", error); for (i = 0; i < num_elem_blk; i++) { ex_get_name(exoid, EX_ELEM_BLOCK, ids[i], name); if (strcmp(name, block_names[i]) != 0) { printf("error in ex_get_name for block id %d\n", ids[i]); } error = ex_get_block(exoid, EX_ELEM_BLOCK, ids[i], elem_type[i], &(num_elem_in_block[i]), &(num_nodes_per_elem[i]), &(num_edges_per_elem[i]), &(num_faces_per_elem[i]), &(num_attr[i])); printf("\nafter ex_get_elem_block, error = %d\n", error); printf("element block id = %2d\n", ids[i]); printf("element block type = '%s'\n", elem_type[i]); printf("num_elem_in_block = %2d\n", num_elem_in_block[i]); printf("num_total_nodes_per_block = %2d\n", num_nodes_per_elem[i]); printf("num_total_edges_per_block = %2d\n", num_edges_per_elem[i]); printf("num_total_faces_per_block = %2d\n", num_faces_per_elem[i]); printf("num_attr = %2d\n", num_attr[i]); printf("name = '%s'\n", block_names[i]); } } /* read connectivity */ for (i = 0; i < num_elem_blk; i++) { if (num_elem_in_block[i] > 0) { if (strcmp(elem_type[i], "NFACED") == 0 || strcmp(elem_type[i], "nfaced") == 0) { int nfaces = 0; connect = (int *)calloc((num_faces_per_elem[i]), sizeof(int)); nnpe = (int *)calloc(num_elem_in_block[i], sizeof(int)); error = ex_get_entity_count_per_polyhedra(exoid, EX_ELEM_BLOCK, ids[i], nnpe); printf("\nafter ex_get_entity_count_per_polyhedra, error = %d\n", error); for (j = 0; j < num_elem_in_block[i]; j++) { nfaces += nnpe[j]; } assert(nfaces == num_faces_per_elem[i]); error = ex_get_conn(exoid, EX_ELEM_BLOCK, ids[i], NULL, NULL, connect); printf("\nafter ex_get_conn, error = %d\n", error); printf("face connectivity array for elem block %2d\n", ids[i]); nfaces = 0; for (j = 0; j < num_elem_in_block[i]; j++) { printf("Element %d, %d faces:\t", j + 1, nnpe[j]); for (k = 0; k < nnpe[j]; k++) { printf("%3d ", connect[nfaces + k]); } printf("\n"); nfaces += nnpe[j]; } /* Now get the faces and their connectivity... */ /* * Convention is that the faces for an nfaced block are in a * face block which has the same id as the element block... * (Or, at least let's try that for awhile and see if it works...) */ /* NOTE: We are overwriting the element block data here... */ error = ex_get_block(exoid, EX_FACE_BLOCK, ids[i], elem_type[i], &(num_face_in_block[i]), &(num_nodes_per_elem[i]), NULL, NULL, &(num_attr[i])); printf("\nafter ex_get_block (EX_FACE_BLOCK), error = %d\n", error); error = ex_get_names(exoid, EX_FACE_BLOCK, block_names); printf("\nafter ex_get_names, error = %3d\n", error); printf("\tface block id = %2d\n", ids[i]); printf("\tface block type = '%s'\n", elem_type[i]); printf("\tnum_face_in_block = %2d\n", num_face_in_block[i]); printf("\tnum_total_nodes_per_block = %2d\n", num_nodes_per_elem[i]); printf("\tnum_attr = %2d\n", num_attr[i]); printf("\tname = '%s'\n", block_names[i]); fconnect = (int *)calloc((num_nodes_per_elem[i]), sizeof(int)); nnpf = (int *)calloc(num_face_in_block[i], sizeof(int)); error = ex_get_entity_count_per_polyhedra(exoid, EX_FACE_BLOCK, ids[i], nnpf); printf("\nafter ex_get_entity_count_per_polyhedra, error = %d\n", error); nnodes = 0; for (j = 0; j < num_face_in_block[i]; j++) { nnodes += nnpf[j]; } assert(nnodes == num_nodes_per_elem[i]); error = ex_get_conn(exoid, EX_FACE_BLOCK, ids[i], fconnect, NULL, NULL); printf("\nafter ex_get_conn, error = %d\n", error); printf("node connectivity array for face block %2d\n", ids[i]); nnodes = 0; for (j = 0; j < num_face_in_block[i]; j++) { printf("Face %d, %d nodes:\t", j + 1, nnpf[j]); for (k = 0; k < nnpf[j]; k++) { printf("%3d ", fconnect[nnodes + k]); } printf("\n"); nnodes += nnpf[j]; } free(fconnect); free(nnpe); free(nnpf); } else { connect = (int *)calloc((num_nodes_per_elem[i] * num_elem_in_block[i]), sizeof(int)); error = ex_get_elem_conn(exoid, ids[i], connect); printf("\nafter ex_get_elem_conn, error = %d\n", error); printf("connect array for elem block %2d\n", ids[i]); for (j = 0; j < num_nodes_per_elem[i]; j++) { printf("%3d\n", connect[j]); } } free(connect); } } for (i = 0; i < num_elem_blk; i++) { free(elem_type[i]); free(block_names[i]); } if (num_elem_blk > 0) { free(ids); free(num_nodes_per_elem); free(num_edges_per_elem); free(num_faces_per_elem); free(num_attr); } /* read QA records */ ex_inquire(exoid, EX_INQ_QA, &num_qa_rec, &fdum, cdum); for (i = 0; i < num_qa_rec; i++) { for (j = 0; j < 4; j++) { qa_record[i][j] = (char *)calloc((MAX_STR_LENGTH + 1), sizeof(char)); } } error = ex_get_qa(exoid, qa_record); printf("\nafter ex_get_qa, error = %3d\n", error); printf("QA records = \n"); for (i = 0; i < num_qa_rec; i++) { for (j = 0; j < 4; j++) { printf(" '%s'\n", qa_record[i][j]); free(qa_record[i][j]); } } /* read information records */ error = ex_inquire(exoid, EX_INQ_INFO, &num_info, &fdum, cdum); printf("\nafter ex_inquire, error = %3d\n", error); for (i = 0; i < num_info; i++) { info[i] = (char *)calloc((MAX_LINE_LENGTH + 1), sizeof(char)); } error = ex_get_info(exoid, info); printf("\nafter ex_get_info, error = %3d\n", error); printf("info records = \n"); for (i = 0; i < num_info; i++) { printf(" '%s'\n", info[i]); free(info[i]); } error = ex_close(exoid); printf("\nafter ex_close, error = %3d\n", error); return 0; }
/*@ DMPlexCreateExodus - Create a DMPlex mesh from an ExodusII file. Collective on comm Input Parameters: + comm - The MPI communicator . exoid - The ExodusII id associated with a exodus file and obtained using ex_open - interpolate - Create faces and edges in the mesh Output Parameter: . dm - The DM object representing the mesh Level: beginner .keywords: mesh,ExodusII .seealso: DMPLEX, DMCreate() @*/ PetscErrorCode DMPlexCreateExodus(MPI_Comm comm, PetscInt exoid, PetscBool interpolate, DM *dm) { #if defined(PETSC_HAVE_EXODUSII) PetscMPIInt num_proc, rank; PetscSection coordSection; Vec coordinates; PetscScalar *coords; PetscInt coordSize, v; PetscErrorCode ierr; /* Read from ex_get_init() */ char title[PETSC_MAX_PATH_LEN+1]; int dim = 0, numVertices = 0, numCells = 0; int num_cs = 0, num_vs = 0, num_fs = 0; #endif PetscFunctionBegin; #if defined(PETSC_HAVE_EXODUSII) ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &num_proc);CHKERRQ(ierr); ierr = DMCreate(comm, dm);CHKERRQ(ierr); ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); /* Open EXODUS II file and read basic informations on rank 0, then broadcast to all processors */ if (!rank) { ierr = ex_get_init(exoid, title, &dim, &numVertices, &numCells, &num_cs, &num_vs, &num_fs); if (ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ExodusII ex_get_init() failed with error code %D\n",ierr); if (!num_cs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Exodus file does not contain any cell set\n"); } ierr = MPI_Bcast(title, PETSC_MAX_PATH_LEN+1, MPI_CHAR, 0, comm);CHKERRQ(ierr); ierr = MPI_Bcast(&dim, 1, MPI_INT, 0, comm);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) *dm, title);CHKERRQ(ierr); ierr = DMPlexSetDimension(*dm, dim);CHKERRQ(ierr); ierr = DMPlexSetChart(*dm, 0, numCells+numVertices);CHKERRQ(ierr); /* Read cell sets information */ if (!rank) { PetscInt *cone; int c, cs, c_loc, v, v_loc; /* Read from ex_get_elem_blk_ids() */ int *cs_id; /* Read from ex_get_elem_block() */ char buffer[PETSC_MAX_PATH_LEN+1]; int num_cell_in_set, num_vertex_per_cell, num_attr; /* Read from ex_get_elem_conn() */ int *cs_connect; /* Get cell sets IDs */ ierr = PetscMalloc(num_cs * sizeof(int), &cs_id);CHKERRQ(ierr); ierr = ex_get_elem_blk_ids(exoid, cs_id);CHKERRQ(ierr); /* Read the cell set connectivity table and build mesh topology EXO standard requires that cells in cell sets be numbered sequentially and be pairwise disjoint. */ /* First set sizes */ for (cs = 0, c = 0; cs < num_cs; cs++) { ierr = ex_get_elem_block(exoid, cs_id[cs], buffer, &num_cell_in_set, &num_vertex_per_cell, &num_attr);CHKERRQ(ierr); for (c_loc = 0; c_loc < num_cell_in_set; ++c_loc, ++c) { ierr = DMPlexSetConeSize(*dm, c, num_vertex_per_cell);CHKERRQ(ierr); } } ierr = DMSetUp(*dm);CHKERRQ(ierr); for (cs = 0, c = 0; cs < num_cs; cs++) { ierr = ex_get_elem_block(exoid, cs_id[cs], buffer, &num_cell_in_set, &num_vertex_per_cell, &num_attr);CHKERRQ(ierr); ierr = PetscMalloc2(num_vertex_per_cell*num_cell_in_set,int,&cs_connect,num_vertex_per_cell,PetscInt,&cone);CHKERRQ(ierr); ierr = ex_get_elem_conn(exoid, cs_id[cs], cs_connect);CHKERRQ(ierr); /* EXO uses Fortran-based indexing, sieve uses C-style and numbers cell first then vertices. */ for (c_loc = 0, v = 0; c_loc < num_cell_in_set; ++c_loc, ++c) { for (v_loc = 0; v_loc < num_vertex_per_cell; ++v_loc, ++v) { cone[v_loc] = cs_connect[v]+numCells-1; } if (dim == 3) { /* Tetrahedra are inverted */ if (num_vertex_per_cell == 4) { PetscInt tmp = cone[0]; cone[0] = cone[1]; cone[1] = tmp; } /* Hexahedra are inverted */ if (num_vertex_per_cell == 8) { PetscInt tmp = cone[1]; cone[1] = cone[3]; cone[3] = tmp; } } ierr = DMPlexSetCone(*dm, c, cone);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(*dm, "Cell Sets", c, cs_id[cs]);CHKERRQ(ierr); } ierr = PetscFree2(cs_connect,cone);CHKERRQ(ierr); } ierr = PetscFree(cs_id);CHKERRQ(ierr); }
/* // Read and EXODUSII database and return a TECPLOT file */ void tec(int exoid, const char *filename) { int i, j, k, idum; int ndim, nnode, nelem, nblk, nnset, neset, nvar, ntime, itime; char title[MAX_LINE_LENGTH + 1]; char * nameco[3], **varnames = NULL; double *x[3], **q = NULL, *time; int * elem_id = NULL, *node_per_elem = NULL, *elem_per_blk = NULL, *attr_per_blk = NULL; int ** icon = NULL, *ic = NULL, izone; char ** elem_type = NULL; int name_size = 0; FILE * tecfile = NULL; void teczone(int, int, int, char *, int, int, int *, int, double **, int, double **, FILE *); /* * FIRST, READ THE EXODUS DATA BASE */ /* * Open the output file, if we can */ tecfile = fopen(filename, "w"); if (tecfile == NULL) { printf("\nCannot open file %s for writing\n\n", filename); exit(1); } /* * Determine max name size used in databsae... */ name_size = ex_inquire_int(exoid, EX_INQ_DB_MAX_USED_NAME_LENGTH); ex_set_max_name_length(exoid, name_size); /* * Read database size, get coordinates and connectivity */ memset(title, 0, MAX_LINE_LENGTH + 1); ex_get_init(exoid, title, &ndim, &nnode, &nelem, &nblk, &nnset, &neset); x[0] = x[1] = x[2] = NULL; for (i = 0; i < ndim; i++) { nameco[i] = (char *)malloc((name_size + 1) * sizeof(char)); x[i] = (double *)malloc(nnode * sizeof(double)); } ex_get_coord_names(exoid, nameco); if (strlen(nameco[0]) == 0) strcpy(nameco[0], "X"); if (strlen(nameco[1]) == 0) strcpy(nameco[1], "Y"); if (ndim > 2) if (strlen(nameco[2]) == 0) strcpy(nameco[2], "Z"); ex_get_coord(exoid, x[0], x[1], x[2]); elem_id = (int *)malloc(nblk * sizeof(int)); node_per_elem = (int *)malloc(nblk * sizeof(int)); elem_per_blk = (int *)malloc(nblk * sizeof(int)); attr_per_blk = (int *)malloc(nblk * sizeof(int)); elem_type = (char **)malloc(nblk * sizeof(char *)); icon = (int **)malloc(nblk * sizeof(int *)); for (i = 0; i < nblk; i++) elem_type[i] = (char *)malloc((name_size + 1) * sizeof(char)); ex_get_elem_blk_ids(exoid, elem_id); for (i = 0; i < nblk; i++) { ex_get_elem_block(exoid, elem_id[i], elem_type[i], &elem_per_blk[i], &node_per_elem[i], &attr_per_blk[i]); icon[i] = (int *)malloc(elem_per_blk[i] * node_per_elem[i] * sizeof(int)); ex_get_elem_conn(exoid, elem_id[i], icon[i]); } /* * Read time step information */ ntime = ex_inquire_int(exoid, EX_INQ_TIME); if (ntime > 0) { time = (double *)malloc(ntime * sizeof(double)); ex_get_all_times(exoid, time); } /* * Read number of nodal variables and save space */ nvar = 0; ex_get_var_param(exoid, "n", &nvar); if (nvar > 0) { varnames = (char **)malloc(nvar * sizeof(char *)); q = (double **)malloc(nvar * sizeof(double *)); for (i = 0; i < nvar; i++) { varnames[i] = (char *)malloc((name_size + 1) * sizeof(char)); q[i] = (double *)malloc(nnode * sizeof(double)); } ex_get_var_names(exoid, "n", nvar, varnames); } /* ///////////////////////////////////////////////////////////////////// // PROMPT USER FOR INFO AND WRITE TECPLOT FILE ///////////////////////////////////////////////////////////////////// */ /* * Write the TECPLOT header information */ assert(strlen(title) < (MAX_LINE_LENGTH + 1)); fprintf(tecfile, "TITLE = \"%s\"\n", title); fprintf(tecfile, "VARIABLES = "); for (i = 0; i < ndim; i++) { fprintf(tecfile, "\"%s\"", nameco[i]); if (i < (ndim - 1)) fprintf(tecfile, ", "); } if (nvar == 0) fprintf(tecfile, "\n"); else fprintf(tecfile, ",\n "); idum = 0; for (i = 0; i < nvar; i++) { idum += strlen(varnames[i]); assert(idum < 1022); fprintf(tecfile, "\"%s\"", varnames[i]); if (i < (nvar - 1)) { if ((i + 1) % 4 == 0) { idum = 0; fprintf(tecfile, ",\n "); } else fprintf(tecfile, ", "); } } fprintf(tecfile, "\n"); /* * Select a time step */ izone = 0; if (ntime == 0) { printf("\nNo solution variables available, saving mesh only\n\n"); izone = 1; } else { printf("\nTime step information:\n\n"); for (i = 0; i < ntime; i++) printf(" Time step %5d, time = %e\n", i + 1, time[i]); do { printf("\nSelect time step number to save,\n"); printf(" or 0 for zone animation of all time steps: "); scanf("%d", &itime); printf("\n"); } while (itime < 0 || itime > ntime); printf("\n"); if (itime == 0) izone = 0; else izone = 1; } /* * Write time steps */ if (izone == 0) { /* * Collapse the zones into one */ /* * Make sure we are using all the same element types * Create one master connectivity array */ for (i = 1; i < nblk; i++) if (strcmp(elem_type[0], elem_type[i]) != 0) { printf("\nCannot create zone animation because\n"); ; printf("\n there are multiple element types."); exit(1); } ic = (int *)malloc(nelem * node_per_elem[0] * sizeof(int)); k = 0; for (j = 0; j < nblk; j++) for (i = 0; i < node_per_elem[j] * elem_per_blk[j]; i++) ic[k++] = icon[j][i]; assert(k == nelem * node_per_elem[0]); if (itime == 0) { for (j = 0; j < ntime; j++) { for (i = 0; i < nvar; i++) ex_get_nodal_var(exoid, j + 1, i + 1, nnode, q[i]); i = 0; teczone(1, nnode, j + 1, elem_type[i], node_per_elem[i], nelem, ic, ndim, x, nvar, q, tecfile); } printf("\n"); } free(ic); } else if (izone == 1) { /* || Write out each zone individually */ for (i = 0; i < nvar; i++) ex_get_nodal_var(exoid, itime, i + 1, nnode, q[i]); for (i = 0; i < nblk; i++) teczone(nblk, nnode, elem_id[i], elem_type[i], node_per_elem[i], elem_per_blk[i], icon[i], ndim, x, nvar, q, tecfile); printf("\n"); } /* ///////////////////////////////////////////////////////////////////// // CLEAN UP ///////////////////////////////////////////////////////////////////// */ fclose(tecfile); /* * Free up allocated memory */ for (i = 0; i < ndim; i++) { free(nameco[i]); free(x[i]); } free(elem_id); free(node_per_elem); free(elem_per_blk); free(attr_per_blk); if (elem_type != NULL) { for (i = 0; i < nblk; i++) { free(elem_type[i]); } free(elem_type); } if (icon != NULL) { for (i = 0; i < nblk; i++) { free(icon[i]); } free(icon); } if (nvar > 0) { if (varnames != NULL) { for (i = 0; i < nvar; i++) { free(varnames[i]); } free(varnames); } if (q != NULL) { for (i = 0; i < nvar; i++) { free(q[i]); } free(q); } } }
int main (int argc, char **argv) { int exoid, num_dim, num_nodes, num_elem, num_elem_blk, num_node_sets; int num_side_sets, error; int i, j, k, node_ctr; int *connect, *node_list, *node_ctr_list, *elem_list, *side_list; int *ids; int *num_elem_per_set; int *num_df_per_set; int *elem_ind, *df_ind; int *num_elem_in_block, *num_nodes_per_elem, *num_attr; int num_elem_in_set; int num_sides_in_set, num_df_in_set; int elem_list_len = 0; int node_list_len = 0; int df_list_len = 0; int CPU_word_size,IO_word_size; int idum; float *dist_fact; float version, fdum; char title[MAX_LINE_LENGTH+1], elem_type[MAX_STR_LENGTH+1]; char *cdum = 0; CPU_word_size = 0; /* sizeof(float) */ IO_word_size = 0; /* use what is stored in file */ ex_opts (EX_VERBOSE | EX_ABORT ); /* open EXODUS II files */ exoid = ex_open ("test.exo", /* filename path */ EX_READ, /* access mode = READ */ &CPU_word_size, /* CPU word size */ &IO_word_size, /* IO word size */ &version); /* ExodusII library version */ printf ("\nafter ex_open\n"); if (exoid < 0) exit(1); printf ("test.exo is an EXODUSII file; version %4.2f\n", version); /* printf (" CPU word size %1d\n",CPU_word_size); */ printf (" I/O word size %1d\n",IO_word_size); ex_inquire(exoid,EX_INQ_API_VERS, &idum, &version, cdum); printf ("EXODUSII API; version %4.2f\n", version); /* ncopts = NC_VERBOSE; */ /* read database parameters */ error = ex_get_init (exoid, title, &num_dim, &num_nodes, &num_elem, &num_elem_blk, &num_node_sets, &num_side_sets); printf ("after ex_get_init, error = %3d\n", error); printf ("database parameters:\n"); printf ("title = '%s'\n",title); printf ("num_dim = %3d\n",num_dim); printf ("num_nodes = %3d\n",num_nodes); printf ("num_elem = %3d\n",num_elem); printf ("num_elem_blk = %3d\n",num_elem_blk); printf ("num_node_sets = %3d\n",num_node_sets); printf ("num_side_sets = %3d\n",num_side_sets); /* read element block parameters */ ids = (int *) calloc(num_elem_blk, sizeof(int)); num_elem_in_block = (int *) calloc(num_elem_blk, sizeof(int)); num_nodes_per_elem = (int *) calloc(num_elem_blk, sizeof(int)); num_attr = (int *) calloc(num_elem_blk, sizeof(int)); error = ex_get_elem_blk_ids (exoid, ids); printf ("\nafter ex_get_elem_blk_ids, error = %3d\n", error); for (i=0; i<num_elem_blk; i++) { error = ex_get_elem_block (exoid, ids[i], elem_type, &(num_elem_in_block[i]), &(num_nodes_per_elem[i]), &(num_attr[i])); printf ("\nafter ex_get_elem_block, error = %d\n", error); printf ("element block id = %2d\n",ids[i]); printf ("element type = '%s'\n", elem_type); printf ("num_elem_in_block = %2d\n",num_elem_in_block[i]); printf ("num_nodes_per_elem = %2d\n",num_nodes_per_elem[i]); printf ("num_attr = %2d\n",num_attr[i]); } /* read element connectivity */ for (i=0; i<num_elem_blk; i++) { connect = (int *) calloc((num_nodes_per_elem[i] * num_elem_in_block[i]), sizeof(int)); error = ex_get_elem_conn (exoid, ids[i], connect); printf ("\nafter ex_get_elem_conn, error = %d\n", error); printf ("connect array for elem block %2d\n", ids[i]); for (j=0; j<num_nodes_per_elem[i]; j++) { printf ("%3d\n", connect[j]); } free (connect); } free(ids); free(num_elem_in_block); free(num_nodes_per_elem); free(num_attr); /* read individual side sets */ ids = (int *) calloc(num_side_sets, sizeof(int)); error = ex_get_side_set_ids (exoid, ids); printf ("\nafter ex_get_side_set_ids, error = %3d\n", error); for (i=0; i<num_side_sets; i++) { error = ex_get_side_set_param (exoid, ids[i], &num_sides_in_set, &num_df_in_set); printf ("\nafter ex_get_side_set_param, error = %3d\n", error); printf ("side set %2d parameters:\n",ids[i]); printf ("num_sides = %3d\n",num_sides_in_set); printf ("num_dist_factors = %3d\n", num_df_in_set); /* Note: The # of elements is same as # of sides! */ num_elem_in_set = num_sides_in_set; elem_list = (int *) calloc(num_elem_in_set, sizeof(int)); side_list = (int *) calloc(num_sides_in_set, sizeof(int)); node_ctr_list = (int *) calloc(num_elem_in_set, sizeof(int)); node_list = (int *) calloc(num_elem_in_set*21, sizeof(int)); dist_fact = (float *) calloc(num_df_in_set, sizeof(float)); error = ex_get_side_set (exoid, ids[i], elem_list, side_list); printf ("\nafter ex_get_side_set, error = %3d\n", error); error = ex_get_side_set_node_list (exoid, ids[i], node_ctr_list, node_list); printf ("\nafter ex_get_side_set_node_list, error = %3d\n", error); if (num_df_in_set > 0) { error = ex_get_side_set_dist_fact (exoid, ids[i], dist_fact); printf ("\nafter ex_get_side_set_dist_fact, error = %3d\n", error); } printf ("element list for side set %2d\n", ids[i]); for (j=0; j<num_elem_in_set; j++) { printf ("%3d\n", elem_list[j]); } printf ("side list for side set %2d\n", ids[i]); for (j=0; j<num_sides_in_set; j++) { printf ("%3d\n", side_list[j]); } node_ctr = 0; printf ("node list for side set %2d\n", ids[i]); for (k=0; k<num_elem_in_set; k++) { printf ("%3d nodes for side %3d\n", node_ctr_list[k], k); for (j=0; j<node_ctr_list[k]; j++) { printf ("%3d\n", node_list[node_ctr+j]); } node_ctr += node_ctr_list[k]; } if (num_df_in_set > 0) { printf ("dist factors for side set %2d\n", ids[i]); for (j=0; j<num_df_in_set; j++) { printf ("%5.3f\n", dist_fact[j]); } } else printf ("no dist factors for side set %2d\n", ids[i]); free (elem_list); free (side_list); free (node_ctr_list); free (node_list); free (dist_fact); } free(ids); if (num_side_sets > 0) { error = ex_inquire(exoid, EX_INQ_SS_ELEM_LEN, &elem_list_len, &fdum, cdum); printf ("\nafter ex_inquire: EX_INQ_SS_ELEM_LEN = %d, error = %d\n", elem_list_len, error); error = ex_inquire(exoid, EX_INQ_SS_NODE_LEN, &node_list_len, &fdum, cdum); printf ("\nafter ex_inquire: EX_INQ_SS_NODE_LEN = %d, error = %d\n", node_list_len, error); error = ex_inquire(exoid, EX_INQ_SS_DF_LEN, &df_list_len, &fdum, cdum); printf ("\nafter ex_inquire: EX_INQ_SS_DF_LEN = %d, error = %d\n", df_list_len, error); } /* read concatenated side sets; this produces the same information as * the above code which reads individual side sets */ /* concatenated side set read */ ids = (int *) calloc(num_side_sets, sizeof(int)); num_elem_per_set = (int *) calloc(num_side_sets, sizeof(int)); num_df_per_set = (int *) calloc(num_side_sets, sizeof(int)); elem_ind = (int *) calloc(num_side_sets, sizeof(int)); df_ind = (int *) calloc(num_side_sets, sizeof(int)); elem_list = (int *) calloc(elem_list_len, sizeof(int)); side_list = (int *) calloc(elem_list_len, sizeof(int)); dist_fact = (float *) calloc(df_list_len, sizeof(float)); error = ex_get_concat_side_sets (exoid, ids, num_elem_per_set, num_df_per_set, elem_ind, df_ind, elem_list, side_list, dist_fact); printf ("\nafter ex_get_concat_side_sets, error = %3d\n", error); printf ("concatenated side set info\n"); printf ("ids = \n"); for (i=0; i<num_side_sets; i++) printf ("%3d\n", ids[i]); printf ("num_elem_per_set = \n"); for (i=0; i<num_side_sets; i++) printf ("%3d\n", num_elem_per_set[i]); printf ("num_dist_per_set = \n"); for (i=0; i<num_side_sets; i++) printf ("%3d\n", num_df_per_set[i]); printf ("elem_ind = \n"); for (i=0; i<num_side_sets; i++) printf ("%3d\n", elem_ind[i]); printf ("dist_ind = \n"); for (i=0; i<num_side_sets; i++) printf ("%3d\n", df_ind[i]); printf ("elem_list = \n"); for (i=0; i<elem_list_len; i++) printf ("%3d\n", elem_list[i]); printf ("side_list = \n"); for (i=0; i<elem_list_len; i++) printf ("%3d\n", side_list[i]); printf ("dist_fact = \n"); for (i=0; i<df_list_len; i++) printf ("%5.3f\n", dist_fact[i]); free (ids); free (num_elem_per_set); free (num_df_per_set); free (df_ind); free (elem_ind); free (elem_list); free (side_list); free (dist_fact); /* end of concatenated side set read */ error = ex_close (exoid); printf ("\nafter ex_close, error = %3d\n", error); return 0; }