/*! \undoc */
int ex_get_concat_side_set_node_count(int exoid, int *side_set_node_cnt_list)
{
  int          ii, i, j, iss, ioff;
  ex_entity_id side_set_id;
  int          num_side_sets, num_elem_blks, ndim;
  int64_t      tot_num_elem = 0, tot_num_ss_elem = 0, num_df = 0, side, elem;
  void_int *   elem_blk_ids       = NULL;
  void_int *   side_set_ids       = NULL;
  void_int *   ss_elem_ndx        = NULL;
  void_int *   side_set_elem_list = NULL;
  void_int *   side_set_side_list = NULL;
  size_t       elem_ctr;
  int          int_size, ids_size;
  int          status;

  struct elem_blk_parm *elem_blk_parms = NULL;

  char errmsg[MAX_ERR_LENGTH];

  exerrval = 0; /* clear error code */

  /* first check if any side sets are specified */
  /* inquire how many side sets have been stored */
  num_side_sets = ex_inquire_int(exoid, EX_INQ_SIDE_SETS);
  if (num_side_sets < 0) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get number of side sets in file id %d",
             exoid);
    ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
    return (EX_FATAL);
  }

  if (num_side_sets == 0) {
    snprintf(errmsg, MAX_ERR_LENGTH, "Warning: no side sets defined in file id %d", exoid);
    ex_err("ex_get_concat_side_set_node_count", errmsg, EX_WARN);
    return (EX_WARN);
  }

  num_elem_blks = ex_inquire_int(exoid, EX_INQ_ELEM_BLK);
  if (num_elem_blks < 0) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get number of element blocks in file id %d",
             exoid);
    ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
    return (EX_FATAL);
  }

  tot_num_elem = ex_inquire_int(exoid, EX_INQ_ELEM);
  if (tot_num_elem < 0) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get total number of elements in file id %d",
             exoid);
    ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* get the dimensionality of the coordinates;  this is necessary to
     distinguish between 2d TRIs and 3d TRIs */
  ndim = ex_inquire_int(exoid, EX_INQ_DIM);
  if (ndim < 0) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get dimensionality in file id %d", exoid);
    ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
    return (EX_FATAL);
  }

  int_size = sizeof(int);
  if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
    int_size = sizeof(int64_t);
  }

  /* Allocate space for the element block ids */
  ids_size = sizeof(int);
  if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
    ids_size = sizeof(int64_t);
  }

  if (!(elem_blk_ids = malloc(num_elem_blks * ids_size))) {
    exerrval = EX_MEMFAIL;
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to allocate space for element block ids for file id %d", exoid);
    ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
    goto error_ret;
  }

  if (ex_get_ids(exoid, EX_ELEM_BLOCK, elem_blk_ids) != EX_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get element block ids in file id %d", exoid);
    ex_err("ex_get_concat_side_set_node_count", errmsg, EX_MSG);
    goto error_ret;
  }

  /* Allocate space for the element block params */
  if (!(elem_blk_parms = malloc(num_elem_blks * sizeof(struct elem_blk_parm)))) {
    exerrval = EX_MEMFAIL;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for element block params "
                                     "for file id %d",
             exoid);
    ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
    goto error_ret;
  }

  elem_ctr = 0;
  for (i = 0; i < num_elem_blks; i++) {
    ex_entity_id id;
    if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
      id = ((int64_t *)elem_blk_ids)[i];
    }
    else {
      id = ((int *)elem_blk_ids)[i];
    }

    if (ex_int_get_block_param(exoid, id, ndim, &elem_blk_parms[i]) != EX_NOERR) {
      goto error_ret;
    }

    elem_ctr += elem_blk_parms[i].num_elem_in_blk;
    elem_blk_parms[i].elem_ctr = elem_ctr; /* save elem number max */
  }

  /* Finally... Create the list of node counts for each face in the
   * side set.
   */
  /* Allocate space for the sideset ids */
  if (!(side_set_ids = malloc(num_side_sets * ids_size))) {
    exerrval = EX_MEMFAIL;
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to allocate space for side set ids for file id %d", exoid);
    ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
    goto error_ret;
  }

  if (ex_get_ids(exoid, EX_SIDE_SET, side_set_ids) != EX_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get side set ids in file id %d", exoid);
    ex_err("ex_get_concat_side_set_node_count", errmsg, EX_MSG);
    goto error_ret;
  }

  /* Lookup index of side set id in VAR_SS_IDS array */
  ioff = 0;
  for (iss = 0; iss < num_side_sets; iss++) {
    if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
      side_set_id = ((int64_t *)side_set_ids)[iss];
    }
    else {
      side_set_id = ((int *)side_set_ids)[iss];
    }

    /* First determine the  # of elements in the side set*/
    if (int_size == sizeof(int64_t)) {
      status = ex_get_set_param(exoid, EX_SIDE_SET, side_set_id, &tot_num_ss_elem, &num_df);
    }
    else {
      int tot, df;
      status          = ex_get_set_param(exoid, EX_SIDE_SET, side_set_id, &tot, &df);
      tot_num_ss_elem = tot;
      num_df          = df;
    }

    if (status != EX_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: failed to get number of elements in side set  %" PRId64 " in file id %d",
               side_set_id, exoid);
      ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
      goto error_ret;
    }

    if (tot_num_ss_elem == 0) {
      continue;
    }

    /* Allocate space for the side set element list */
    if (!(side_set_elem_list = malloc(tot_num_ss_elem * int_size))) {
      exerrval = EX_MEMFAIL;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set element "
                                       "list for file id %d",
               exoid);
      ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
      goto error_ret;
    }

    /* Allocate space for the side set side list */
    if (!(side_set_side_list = malloc(tot_num_ss_elem * int_size))) {
      exerrval = EX_MEMFAIL;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set side list "
                                       "for file id %d",
               exoid);
      ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
      goto error_ret;
    }

    if (ex_get_set(exoid, EX_SIDE_SET, side_set_id, side_set_elem_list, side_set_side_list) !=
        EX_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get side set  %" PRId64 " in file id %d",
               side_set_id, exoid);
      ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
      goto error_ret;
    }

    /* Allocate space for the ss element index array */
    if (!(ss_elem_ndx = malloc(tot_num_ss_elem * int_size))) {
      exerrval = EX_MEMFAIL;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to allocate space for side set elem sort "
                                       "array for file id %d",
               exoid);
      ex_err("ex_get_concat_side_set_node_count", errmsg, exerrval);
      goto error_ret;
    }

    /* Sort side set element list into index array  - non-destructive */
    if (int_size == sizeof(int64_t)) {
      /* Sort side set element list into index array  - non-destructive */
      int64_t *elems = (int64_t *)ss_elem_ndx;
      for (i = 0; i < tot_num_ss_elem; i++) {
        elems[i] = i; /* init index array to current position */
      }
      ex_iqsort64(side_set_elem_list, ss_elem_ndx, tot_num_ss_elem);
    }
    else {
      /* Sort side set element list into index array  - non-destructive */
      int *elems = (int *)ss_elem_ndx;
      for (i = 0; i < tot_num_ss_elem; i++) {
        elems[i] = i; /* init index array to current position */
      }
      ex_iqsort(side_set_elem_list, ss_elem_ndx, tot_num_ss_elem);
    }

    j = 0; /* The current element block... */
    for (ii = 0; ii < tot_num_ss_elem; ii++) {

      int64_t elem_ndx;
      if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
        elem_ndx = ((int64_t *)ss_elem_ndx)[ii];
        elem     = ((int64_t *)side_set_elem_list)[elem_ndx];
        side     = ((int64_t *)side_set_side_list)[elem_ndx] - 1;
      }
      else {
        elem_ndx = ((int *)ss_elem_ndx)[ii];
        elem     = ((int *)side_set_elem_list)[elem_ndx];
        side     = ((int *)side_set_side_list)[elem_ndx] - 1;
      }

      /*
       * Since the elements are being accessed in sorted, order, the
       * block that contains the elements must progress sequentially
       * from block 0 to block[num_elem_blks-1]. Once we find an element
       * not in this block, find a following block that contains it...
       */
      for (; j < num_elem_blks; j++) {
        if (elem <= elem_blk_parms[j].elem_ctr) {
          break;
        }
      }

      if (j < num_elem_blks) {
        assert(side < elem_blk_parms[j].num_sides);
        side_set_node_cnt_list[elem_ndx + ioff] = elem_blk_parms[j].num_nodes_per_side[side];
      }
      else {
        exerrval = EX_BADPARAM;
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Invalid element number  %" PRId64
                                         " found in side set  %" PRId64 " in file %d",
                 elem, side_set_id, exoid);
        ex_err("ex_get_concat_side_set_node_count", errmsg, EX_MSG);
        goto error_ret;
      }
    }
    ss_elem_ndx        = ex_safe_free(ss_elem_ndx);
    side_set_elem_list = ex_safe_free(side_set_elem_list);
    side_set_side_list = ex_safe_free(side_set_side_list);
    ioff += tot_num_ss_elem;
  }

  /* All done: release allocated memory */
  ex_safe_free(elem_blk_ids);
  ex_safe_free(side_set_ids);
  ex_safe_free(ss_elem_ndx);
  ex_safe_free(side_set_elem_list);
  ex_safe_free(side_set_side_list);
  ex_safe_free(elem_blk_parms);
  return (EX_NOERR);

error_ret:
  ex_safe_free(elem_blk_ids);
  ex_safe_free(side_set_ids);
  ex_safe_free(ss_elem_ndx);
  ex_safe_free(side_set_elem_list);
  ex_safe_free(side_set_side_list);
  ex_safe_free(elem_blk_parms);
  return (EX_FATAL);
}
Exemplo n.º 2
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);
}
Exemplo n.º 3
0
int ex_put_concat_sets (int   exoid,
			ex_entity_type set_type,
			const struct ex_set_specs* set_specs)
{
  int status;
  int temp;
  const void_int  *num_entries_per_set = set_specs->num_entries_per_set;
  const void_int  *num_dist_per_set = set_specs->num_dist_per_set;
  const void_int  *sets_entry_index = set_specs->sets_entry_index;
  const void_int  *sets_dist_index = set_specs->sets_dist_index;
  const void *sets_dist_fact = set_specs->sets_dist_fact;
  size_t i, num_df, num_entry;
  int cur_num_sets, num_sets;
  int dimid, varid, set_id_ndx, dims[1];
  int  *set_stat = NULL;
  int set_int_type, int_size;

  const float *flt_dist_fact = NULL;
  const double *dbl_dist_fact = NULL;
  char errmsg[MAX_ERR_LENGTH];
  char* idsptr = NULL;
  char* statptr = NULL;
  char* numdfptr = NULL;
  char* factptr = NULL;
  char* elemptr = NULL;
  char* extraptr = NULL;
  ex_inquiry ex_inq_val;

  exerrval = 0; /* clear error code */

  int_size = sizeof(int);
  if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
    int_size = sizeof(int64_t);
  }
  
  /* setup pointers based on set_type 
     NOTE: there is another block that sets more stuff later ... */

  if (set_type == EX_NODE_SET) {
    ex_inq_val = EX_INQ_NODE_SETS;
    idsptr = VAR_NS_IDS;
    statptr = VAR_NS_STAT;
  }
  else if (set_type == EX_EDGE_SET) {
    ex_inq_val = EX_INQ_EDGE_SETS;
    idsptr = VAR_ES_IDS;
    statptr = VAR_ES_STAT;
  }
  else if (set_type == EX_FACE_SET) {
    ex_inq_val = EX_INQ_FACE_SETS;
    idsptr = VAR_FS_IDS;
    statptr = VAR_FS_STAT;
  }
  else if (set_type == EX_SIDE_SET) {
    ex_inq_val = EX_INQ_SIDE_SETS;
    idsptr = VAR_SS_IDS;
    statptr = VAR_SS_STAT;
  }
  else if (set_type == EX_ELEM_SET) {
    ex_inq_val = EX_INQ_ELEM_SETS;
    idsptr = VAR_ELS_IDS;
    statptr = VAR_ELS_STAT;
  }
  else {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: invalid set type (%d)", set_type);
    ex_err("ex_put_set_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* first check if any sets are specified */
  if ((status = nc_inq_dimid(exoid, ex_dim_num_objects(set_type), &temp)) != NC_NOERR) {
    if (status == NC_EBADDIM) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: no %ss defined for file id %d", ex_name_of_object(set_type), exoid);
      ex_err("ex_put_concat_sets",errmsg,exerrval);
    } else {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to locate %ss defined in file id %d",
	      ex_name_of_object(set_type), exoid);
      ex_err("ex_put_concat_sets",errmsg,exerrval);
    }
    return (EX_FATAL);
  }
   
  /* inquire how many sets are to be stored */
  num_sets = ex_inquire_int(exoid, ex_inq_val);
  if (num_sets < 0) {
    sprintf(errmsg,
	    "Error: failed to get number of %ss defined for file id %d",
	    ex_name_of_object(set_type), exoid);
    /* use error val from inquire */
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* Fill out set status array */

  /* First, allocate space for the status list */
  if (!(set_stat= malloc(num_sets*sizeof(int)))) {
    exerrval = EX_MEMFAIL;
    sprintf(errmsg,
	    "Error: failed to allocate space for %s status array in file id %d",
	    ex_name_of_object(set_type), exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    return (EX_FATAL);
  }

  if (int_size == sizeof(int64_t)) {
    for (i=0;i<num_sets;i++)  {
      set_stat[i] = (((int64_t*)num_entries_per_set)[i] == 0) ? 0 : 1;
    }
  } else {
    for (i=0;i<num_sets;i++)  {
      set_stat[i] = (((int*)num_entries_per_set)[i] == 0) ? 0 : 1;
    }
  }

  /* Next, get variable id of status array */
  if ((status = nc_inq_varid(exoid, statptr, &varid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate %s status in file id %d", 
	    ex_name_of_object(set_type), exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  status = nc_put_var_int(exoid, varid, set_stat);

  if (status != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store %s status array to file id %d",
	    ex_name_of_object(set_type), exoid);
    ex_err("ex_put_concat_set",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  /* put netcdf file into define mode  */
  if ((status = nc_redef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to put file id %d into define mode",
	    exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  /* create set definitions */
  for (i=0; i<num_sets; i++) {
    int64_t set_id;
    if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
      set_id = ((int64_t*)set_specs->sets_ids)[i];
    } else {
      set_id = ((int*)set_specs->sets_ids)[i];
    }

    /* Keep track of the total number of sets defined using a counter stored
       in a linked list keyed by exoid.
       NOTE: ex_get_file_item  is used to find the number of sets of type
       for a specific file and returns that value.
    */
    cur_num_sets=ex_get_file_item(exoid, ex_get_counter_list(set_type));
    if (cur_num_sets >= num_sets) {
      exerrval = EX_FATAL;
      sprintf(errmsg,
	      "Error: exceeded number of %ss (%d) defined in file id %d",
	      ex_name_of_object(set_type), num_sets,exoid);
      ex_err("ex_put_concat_sets",errmsg,exerrval);
      goto error_ret;
    }

    /*   NOTE: ex_inc_file_item  is used to find the number of sets
	 for a specific file and returns that value incremented. */

    cur_num_sets=ex_inc_file_item(exoid, ex_get_counter_list(set_type));
    set_id_ndx = cur_num_sets + 1;
    
    /* setup more pointers based on set_type */
    if (set_type == EX_NODE_SET) {
      elemptr = VAR_NODE_NS(set_id_ndx);
      extraptr = NULL;
      /* note we are using DIM_NUM_NODE_NS instead of DIM_NUM_DF_NS */
      numdfptr = DIM_NUM_NOD_NS(set_id_ndx);
      factptr = VAR_FACT_NS(set_id_ndx);
    }
    else if (set_type == EX_EDGE_SET) {
      elemptr = VAR_EDGE_ES(set_id_ndx);
      extraptr = VAR_ORNT_ES(set_id_ndx);
      numdfptr = DIM_NUM_DF_ES(set_id_ndx);
      factptr = VAR_FACT_ES(set_id_ndx);
    }
    else if (set_type == EX_FACE_SET) {
      elemptr = VAR_FACE_FS(set_id_ndx);
      extraptr = VAR_ORNT_FS(set_id_ndx);
      numdfptr = DIM_NUM_DF_FS(set_id_ndx);
      factptr = VAR_FACT_FS(set_id_ndx);
    }
    else if (set_type == EX_SIDE_SET) {
      elemptr = VAR_ELEM_SS(set_id_ndx);
      extraptr = VAR_SIDE_SS(set_id_ndx);
      numdfptr = DIM_NUM_DF_SS(set_id_ndx);
      factptr = VAR_FACT_SS(set_id_ndx);
    }
    if (set_type == EX_ELEM_SET) {
      elemptr = VAR_ELEM_ELS(set_id_ndx);
      extraptr = NULL;
      numdfptr = DIM_NUM_DF_ELS(set_id_ndx);
      factptr = VAR_FACT_ELS(set_id_ndx);
    }

    /*  define dimension for number of entries per set */
    if (set_stat[i] == 0) /* Is this a NULL set? */
      continue; /* Do not create anything for NULL sets! */

    if (int_size == sizeof(int)) {
      status = nc_def_dim(exoid, ex_dim_num_entries_in_object(set_type, set_id_ndx),
			  ((int*)num_entries_per_set)[i], &dimid);
    } else {
      status = nc_def_dim(exoid, ex_dim_num_entries_in_object(set_type, set_id_ndx),
			  ((int64_t*)num_entries_per_set)[i], &dimid);
    }
    
    if (status != NC_NOERR) {
      if (status == NC_ENAMEINUSE) {
	exerrval = status;
	sprintf(errmsg,
		"Error: %s entry count %"PRId64" already defined in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_concat_sets",errmsg,exerrval);
      } else {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define number of entries for %s %"PRId64" in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_concat_sets",errmsg,exerrval);
      }
      goto error_ret;
    }

    /* create element list variable for set */
    set_int_type = NC_INT;
    if (ex_int64_status(exoid) & EX_BULK_INT64_DB) {
      set_int_type = NC_INT64;
    }

    dims[0] = dimid;
    if ((status = nc_def_var(exoid,elemptr,set_int_type,1,dims, &temp)) != NC_NOERR) {
      if (status == NC_ENAMEINUSE) {
	exerrval = status;
	sprintf(errmsg,
		"Error: element list already exists for %s %"PRId64" in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_concat_sets",errmsg,exerrval);
      } else {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to create element list for %s %"PRId64" in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_concat_sets",errmsg,exerrval);
      }
      goto error_ret;            /* exit define mode and return */
    }
    ex_compress_variable(exoid, temp, 1);

    /* create extra list variable for set  (only for edge, face and side sets) */
    if (extraptr) {
      if ((status = nc_def_var(exoid,extraptr,set_int_type,1,dims, &temp)) != NC_NOERR) { 
	if (status == NC_ENAMEINUSE) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: extra list already exists for %s %"PRId64" in file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	} else {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to create extra list for %s %"PRId64" in file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	}
	goto error_ret;         /* exit define mode and return */
      }
      ex_compress_variable(exoid, temp, 1);
    }

    /*  define dimension for number of dist factors per set */
    /*  NOTE: only define df count if the dist factors exist! */
    if (int_size == sizeof(int64_t)) {
      num_df = ((int64_t*)num_dist_per_set)[i];
      num_entry = ((int64_t*)num_entries_per_set)[i];
    } else {
      num_df = ((int*)num_dist_per_set)[i];
      num_entry = ((int*)num_entries_per_set)[i];
    }

    if (num_df > 0) {
      
      if (set_type == EX_NODE_SET) {
	if (num_df != num_entry) {
	  exerrval = EX_FATAL;
	  sprintf(errmsg,
		  "Error: # dist fact (%"ST_ZU") not equal to # nodes (%"ST_ZU") in node set %"PRId64" file id %d",
		  num_df, num_entry, set_id,exoid);
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	  goto error_ret;          /* exit define mode and return */
	}

	/* resuse dimid from entry lists */
      } else  {
	if ((status = nc_def_dim(exoid, numdfptr,
				 num_df, &dimid)) != NC_NOERR) {
	  if (status == NC_ENAMEINUSE) {
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: %s df count %"PRId64" already defined in file id %d",
		    ex_name_of_object(set_type), set_id,exoid);
	    ex_err("ex_put_concat_sets",errmsg,exerrval);
	  } else {
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: failed to define %s df count for set %"PRId64" in file id %d",
		    ex_name_of_object(set_type), set_id,exoid);
	    ex_err("ex_put_concat_sets",errmsg,exerrval);
	  }
	  goto error_ret;
	}
      }

      /* create distribution factor list variable for set */
      dims[0] = dimid;
      if ((status = nc_def_var(exoid, factptr, nc_flt_code(exoid), 1, dims, &temp)) != NC_NOERR) {
	if (status == NC_ENAMEINUSE) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: dist factor list already exists for %s %"PRId64" in file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	} else {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to create dist factor list for %s %"PRId64" in file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	}
	goto error_ret;            /* exit define mode and return */
      }
      ex_compress_variable(exoid, temp, 2);
    } /* end define dist factors */
  }

  /* leave define mode  */
  if ((status = nc_enddef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to complete definition in file id %d",
	    exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  /* Next, fill out set ids array */

  /* first get id of set ids array variable */
  if ((status = nc_inq_varid(exoid, idsptr, &varid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate %s ids array in file id %d",
	    ex_name_of_object(set_type), exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  /* then, write out set id list */
  if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
    status = nc_put_var_longlong(exoid, varid, set_specs->sets_ids);
  } else {
    status = nc_put_var_int(exoid, varid, set_specs->sets_ids);
  }

  if (status != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store %s id array in file id %d",
	    ex_name_of_object(set_type), exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  /* If the sets_entry_index is passed in as a NULL pointer, then
   *  the user only wants us to define the sets and not populate
   *  the data structures.
   */
  if (sets_entry_index == 0) {
    ex_safe_free(set_stat);
    return(EX_NOERR);
  }
  
  /* Now, use ExodusII call to store sets */
  for (i=0; i<num_sets; i++) {
    int64_t set_id;
    size_t df_ndx;
    
    if (set_stat[i] == 0) /* Is this a NULL set? */
      continue; /* Do not create anything for NULL sets! */

    if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
      set_id = ((int64_t*)set_specs->sets_ids)[i];
    } else {
      set_id = ((int*)set_specs->sets_ids)[i];
    }

    if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
      int64_t* extra_list = NULL;
      /* set extra list */
      if (set_type == EX_EDGE_SET || set_type == EX_FACE_SET || set_type == EX_SIDE_SET)
	extra_list = &(((int64_t*)set_specs->sets_extra_list)[((int64_t*)sets_entry_index)[i]]);
      
      status = ex_put_set(exoid, set_type, set_id, 
			  &(((int64_t*)set_specs->sets_entry_list)[((int64_t*)sets_entry_index)[i]]),
			  extra_list);
    } else {
      int* extra_list = NULL;
      /* set extra list */
      if (set_type == EX_EDGE_SET || set_type == EX_FACE_SET || set_type == EX_SIDE_SET)
	extra_list = &(((int*)set_specs->sets_extra_list)[((int*)sets_entry_index)[i]]);
      
      status = ex_put_set(exoid, set_type, set_id, 
			  &(((int*)set_specs->sets_entry_list)[((int*)sets_entry_index)[i]]),
			  extra_list);
    }
    if (status != NC_NOERR) {
      ex_safe_free(set_stat);
      return(EX_FATAL); /* error will be reported by subroutine */
    }

    if (int_size == sizeof(int)) {
      num_df = ((int*)num_dist_per_set)[i];
      df_ndx = ((int*)sets_dist_index)[i];
    } else {
      num_df = ((int64_t*)num_dist_per_set)[i];
      df_ndx = ((int64_t*)sets_dist_index)[i];
    }

    if (ex_comp_ws(exoid) == sizeof(float)) {
      flt_dist_fact = sets_dist_fact;
      if (num_df > 0) {     /* store dist factors if required */
	if (ex_put_set_dist_fact(exoid, set_type, set_id,
				 &(flt_dist_fact[df_ndx])) == -1) {
	  sprintf(errmsg,
		  "Error: failed to store %s %"PRId64" dist factors for file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  /* use error val from exodusII routine */
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	  ex_safe_free(set_stat);
	  return (EX_FATAL);
	}
      }
    } else if (ex_comp_ws(exoid) == sizeof(double)) {
      dbl_dist_fact = sets_dist_fact;
      if (num_df) {             /* only store if they exist */
	if (ex_put_set_dist_fact(exoid, set_type, set_id,
				 &(dbl_dist_fact[df_ndx])) == -1) {
	  sprintf(errmsg,
		  "Error: failed to store %s %"PRId64" dist factors for file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  /* use error val from exodusII routine */
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	  ex_safe_free(set_stat);
	  return (EX_FATAL);
	}
      }
    } else {
      /* unknown floating point word size */
      exerrval = EX_BADPARAM;
      sprintf(errmsg,
	      "Error: unsupported floating point word size %d for file id %d",
	      ex_comp_ws(exoid), exoid);
      ex_err("ex_put_concat_sets", errmsg, exerrval);
      ex_safe_free(set_stat);
      return (EX_FATAL);
    }
  }
  ex_safe_free(set_stat);
  return(EX_NOERR);


  /* Fatal error: exit definition mode and return */
 error_ret:
  ex_safe_free(set_stat);

  if (nc_enddef (exoid) != NC_NOERR)     /* exit define mode */
    {
      sprintf(errmsg,
	      "Error: failed to complete definition for file id %d",
	      exoid);
      ex_err("ex_put_concat_sets",errmsg,exerrval);
    }
  return (EX_FATAL);
}