Пример #1
0
/* get element block ids and block parameters */
int c_ex_get_elem_block_parameters(int *exoid, int *num_elem_blk, int *block_ids, int *num_elem_in_block, int *num_nodes_per_elem)
{
   int error=0;
#ifdef HAVE_LIBEXOIIV2C
   char elem_type[MAX_STR_LENGTH+1];
   int *num_attr;
   int i;
   // Get element block ids:
   error = ex_get_elem_blk_ids(*exoid, block_ids);
   // Get element type of blocks, number of elements in blocks, and
   // number of nodes per element:
   num_attr = (int *) calloc(*num_elem_blk, sizeof(int));
   
   for (i=0; i<*num_elem_blk; i++)
   {
      error = ex_get_elem_block(*exoid,
                                block_ids[i],
                                elem_type,
                                &(num_elem_in_block[i]),
                                &(num_nodes_per_elem[i]),
                                &(num_attr[i]));
   }
   free(num_attr);
#else
   FLExit("Fluidity was not configured with exodusII, reconfigure with '--with-exodusii'!");
#endif
   return (error);
}
Пример #2
0
/* get element block ids only */
int c_ex_get_elem_blk_ids(int *exoid, int *block_ids)
{
   int error=0;
#ifdef HAVE_LIBEXOIIV2C
   error = ex_get_elem_blk_ids(*exoid, block_ids);
#else
   FLExit("Fluidity was not configured with exodusII, reconfigure with '--with-exodusii'!");
#endif
   return (error);
}
Пример #3
0
int read_mesh_params(const std::string &exo_file,
                     Problem_Description* problem,
                     Mesh_Description<INT>* mesh,
                     Sphere_Info* sphere
  )
{
  int    exoid, cpu_ws=0, io_ws=0;
  float  version;
  char   elem_type[MAX_STR_LENGTH+1];
/*---------------------------Execution Begins--------------------------------*/

  /* Open the ExodusII geometry file */
  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 file for mesh params");
    return 0;
  }

  /* Get the init info */
  ex_init_params exo;
  if(ex_get_init_ext(exoid, &exo))
  {
    Gen_Error(0, "fatal: unable to get init info from ExodusII file");
    ex_close(exoid);
    return 0;
  }
  strcpy(mesh->title, exo.title);
  mesh->num_dims      = exo.num_dim;
  mesh->num_nodes     = exo.num_nodes;
  mesh->num_elems     = exo.num_elem;
  mesh->num_el_blks   = exo.num_elem_blk;
  mesh->num_node_sets = exo.num_node_sets;
  mesh->num_side_sets = exo.num_side_sets;

  /* Get the length of the concatenated node set node list */
  if(mesh->num_node_sets > 0)
  {
    mesh->ns_list_len = ex_inquire_int(exoid, EX_INQ_NS_NODE_LEN);
  }
  else
    mesh->ns_list_len = 0;

  /* Allocate and initialize memory for the sphere adjustment */
  sphere->adjust = (int*)malloc(sizeof(int)*3*(mesh->num_el_blks));
  if(!(sphere->adjust)) {
    Gen_Error(0, "fatal: insufficient memory");
    ex_close(exoid);
    return 0;
  }
  else {
    sphere->begin = sphere->adjust + mesh->num_el_blks;
    sphere->end   = sphere->begin  + mesh->num_el_blks;
    for(size_t cnt=0; cnt < mesh->num_el_blks; cnt++) {
      sphere->adjust[cnt] = 0;
      sphere->begin[cnt]  = 0;
      sphere->end[cnt]    = 0;
    }
  }

  std::vector<INT> el_blk_ids(mesh->num_el_blks);

  /* Read the element block IDs */
  if(ex_get_elem_blk_ids(exoid, &el_blk_ids[0]) < 0) {
    Gen_Error(0, "fatal: unable to get element block IDs");
    ex_close(exoid);
    return 0;
  }

  /* Determine the maximum number of nodes per element */
  mesh->max_np_elem = 0;
  for(size_t cnt=0; cnt < mesh->num_el_blks; cnt++) {
    INT num_elems, idum;
    INT nodes_in_elem;
    
    if(ex_get_elem_block(exoid, el_blk_ids[cnt], elem_type,
                         &num_elems, &nodes_in_elem, &idum) < 0)
    {
      Gen_Error(0, "fatal: unable to get element block");
      ex_close(exoid);
      return 0;
    }

    if(cnt == 0)
      sphere->end[0] = num_elems;

    if(get_elem_type(elem_type, nodes_in_elem, mesh->num_dims) == SPHERE && problem->no_sph != 1) {
      sphere->num  += num_elems;
      sphere->adjust[cnt] = 0;
    }
    else
      sphere->adjust[cnt] = sphere->num;

    if(cnt != 0) {
      sphere->begin[cnt] = sphere->end[cnt-1];
      sphere->end[cnt]   = sphere->begin[cnt] + num_elems;
    }

    mesh->max_np_elem = MAX(mesh->max_np_elem, (size_t)nodes_in_elem);
  }

  /* Close the ExodusII file */
  if(ex_close(exoid) < 0)
    Gen_Error(1, "warning: unable to close ExodusII file");

  printf("ExodusII mesh information\n");
  if(strlen(mesh->title) > 0)
    printf("\ttitle: %s\n", mesh->title);
  printf("\tgeometry dimension: "ST_ZU"\n", mesh->num_dims);
  printf("\tnumber of nodes: "ST_ZU"\tnumber of elements: "ST_ZU"\n", mesh->num_nodes,
         mesh->num_elems);
  printf("\tnumber of element blocks: "ST_ZU"\n", mesh->num_el_blks);
  printf("\tnumber of node sets: "ST_ZU"\tnumber of side sets: "ST_ZU"\n",
         mesh->num_node_sets, mesh->num_side_sets);

  return 1;

} /*--------------------------End read_mesh_params()-------------------------*/
Пример #4
0
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;
}
Пример #5
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);
}
Пример #6
0
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;
}
Пример #7
0
int write_vis(std::string &nemI_out_file,
	      std::string &exoII_inp_file,
	      Machine_Description* machine,
	      Problem_Description* prob,
	      Mesh_Description<INT>* mesh,
	      LB_Description<INT>* lb)
{
  int    exid_vis, exid_inp;

  char  title[MAX_LINE_LENGTH+1];
  const char   *coord_names[] = {"X", "Y", "Z"};

  /*-----------------------------Execution Begins------------------------------*/

  /* Generate the file name for the visualization file */
  std::string vis_file_name = remove_extension(nemI_out_file);
  vis_file_name += "-vis.exoII";

  /* Generate the title for the file */
  strcpy(title, UTIL_NAME);
  strcat(title, " ");
  strcat(title, ELB_VERSION);
  strcat(title, " load balance visualization file");

  /*
   * If the vis technique is to be by element block then calculate the
   * number of element blocks.
   */
  int    vis_nelem_blks;
  if(prob->type == ELEMENTAL)
    vis_nelem_blks = machine->num_procs;
  else
    vis_nelem_blks = machine->num_procs + 1;

  /* Create the ExodusII file */
  std::cout << "Outputting load balance visualization file " << vis_file_name.c_str() << "\n";
  int cpu_ws = 0;
  int io_ws = 0;
  int mode = EX_CLOBBER;
  if (prob->int64db|prob->int64api) {
    mode |= EX_NETCDF4|EX_NOCLASSIC|prob->int64db|prob->int64api;
  }
  if((exid_vis=ex_create(vis_file_name.c_str(), mode, &cpu_ws, &io_ws)) < 0) {
    Gen_Error(0, "fatal: unable to create visualization output file");
    return 0;
  }
  ON_BLOCK_EXIT(ex_close, exid_vis);

  /*
   * Open the original input ExodusII file, read the values for the
   * element blocks and output them to the visualization file.
   */
  int icpu_ws=0;
  int iio_ws=0;
  float vers=0.0;
  mode = EX_READ | prob->int64api;
  if((exid_inp=ex_open(exoII_inp_file.c_str(), mode, &icpu_ws, &iio_ws, &vers)) < 0) {
    Gen_Error(0, "fatal: unable to open input ExodusII file");
    return 0;
  }
  ON_BLOCK_EXIT(ex_close, exid_inp);
  
  char **elem_type  = (char**)array_alloc(2, mesh->num_el_blks, MAX_STR_LENGTH+1,
					  sizeof(char));
  if(!elem_type) {
    Gen_Error(0, "fatal: insufficient memory");
    return 0;
  }
  ON_BLOCK_EXIT(free, elem_type);

  std::vector<INT> el_blk_ids(mesh->num_el_blks);
  std::vector<INT> el_cnt_blk(mesh->num_el_blks);
  std::vector<INT> node_pel_blk(mesh->num_el_blks);
  std::vector<INT> nattr_el_blk(mesh->num_el_blks);

  if(ex_get_elem_blk_ids(exid_inp, TOPTR(el_blk_ids)) < 0) {
    Gen_Error(0, "fatal: unable to get element block IDs");
    return 0;
  }

  int acc_vis = ELB_TRUE; // Output a different element block per processor
  if (prob->vis_out == 2)
    acc_vis = ELB_FALSE; // Output a nodal/element variable showing processor

  size_t nsize = 0;

  /*
   * Find out if the mesh consists of mixed elements. If not then
   * element blocks will be used to visualize the partitioning. Otherwise
   * nodal/element results will be used.
   */
  for(size_t ecnt=0; ecnt < mesh->num_el_blks; ecnt++) {
    if(ex_get_elem_block(exid_inp, el_blk_ids[ecnt], elem_type[ecnt],
			 &el_cnt_blk[ecnt], &node_pel_blk[ecnt],
			 &nattr_el_blk[ecnt]) < 0) {
      Gen_Error(0, "fatal: unable to get element block parameters");
      return 0;
    }

    nsize += el_cnt_blk[ecnt]*node_pel_blk[ecnt];

    if(strcmp(elem_type[0], elem_type[ecnt]) == 0) {
      if(node_pel_blk[0] != node_pel_blk[ecnt])
	acc_vis = ELB_FALSE;
    }
    else
      acc_vis = ELB_FALSE;
  }

  if(acc_vis == ELB_TRUE) {
    /* Output the initial information */
    if(ex_put_init(exid_vis, title, mesh->num_dims, mesh->num_nodes,
		   mesh->num_elems, vis_nelem_blks, 0, 0) < 0) {
      Gen_Error(0, "fatal: unable to output initial params to vis file");
      return 0;
    }
	
    /* Output the nodal coordinates */
    float *xptr = nullptr;
    float *yptr = nullptr;
    float *zptr = nullptr;
    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_put_coord(exid_vis, xptr, yptr, zptr) < 0) {
      Gen_Error(0, "fatal: unable to output coords to vis file");
      return 0;
    }
	
    if(ex_put_coord_names(exid_vis, (char**)coord_names) < 0) {
      Gen_Error(0, "fatal: unable to output coordinate names");
      return 0;
    }

    std::vector<INT> elem_block(mesh->num_elems);
    std::vector<INT> elem_map(mesh->num_elems);
    std::vector<INT> tmp_connect(nsize);
    for(size_t ecnt=0; ecnt < mesh->num_elems; ecnt++) {
      elem_map[ecnt] = ecnt+1;
      if(prob->type == ELEMENTAL)
	elem_block[ecnt] = lb->vertex2proc[ecnt];
      else {
	int proc   = lb->vertex2proc[mesh->connect[ecnt][0]];
	int nnodes = get_elem_info(NNODES, mesh->elem_type[ecnt]);
	elem_block[ecnt] = proc;
	for(int ncnt=1; ncnt < nnodes; ncnt++) {
	  if(lb->vertex2proc[mesh->connect[ecnt][ncnt]] != proc) {
	    elem_block[ecnt] = machine->num_procs;
	    break;
	  }
	}
      }
    }

    int ccnt = 0;
    std::vector<INT> vis_el_blk_ptr(vis_nelem_blks+1);
    for(INT bcnt=0; bcnt < vis_nelem_blks; bcnt++) {
      vis_el_blk_ptr[bcnt] = ccnt;
      int pos = 0;
      int old_pos = 0;
      INT* el_ptr = TOPTR(elem_block);
      size_t ecnt   = mesh->num_elems;
      while(pos != -1) {
	pos = in_list(bcnt, ecnt, el_ptr);
	if(pos != -1) {
	  old_pos += pos + 1;
	  ecnt     = mesh->num_elems - old_pos;
	  el_ptr   = TOPTR(elem_block) + old_pos;
	  int nnodes = get_elem_info(NNODES, mesh->elem_type[old_pos-1]);
	  for(int ncnt=0; ncnt < nnodes; ncnt++)
	    tmp_connect[ccnt++] = mesh->connect[old_pos-1][ncnt] + 1;
	}
      }
    }
    vis_el_blk_ptr[vis_nelem_blks] = ccnt;
	
    /* Output the element map */
    if(ex_put_map(exid_vis, TOPTR(elem_map)) < 0) {
      Gen_Error(0, "fatal: unable to output element number map");
      return 0;
    }
	
    /* Output the visualization element blocks */
    for(int bcnt=0; bcnt < vis_nelem_blks; bcnt++) {
      /*
       * Note this assumes all the blocks contain the same type
       * element.
       */
      int ecnt = (vis_el_blk_ptr[bcnt+1]-vis_el_blk_ptr[bcnt])/node_pel_blk[0];
      if(ex_put_elem_block(exid_vis, bcnt+1, elem_type[0],
			   ecnt, node_pel_blk[0], 0) < 0) {
	Gen_Error(0, "fatal: unable to output element block params");
	return 0;
      }
	  
      /* Output the connectivity */
      if(ex_put_elem_conn(exid_vis, bcnt+1,
			  &tmp_connect[vis_el_blk_ptr[bcnt]]) < 0) {
	Gen_Error(0, "fatal: unable to output element connectivity");
	return 0;
      }
    }
  }

  else {	/* For nodal/element results visualization of the partioning. */
    // Copy the mesh portion to the vis file.
    ex_copy(exid_inp, exid_vis);

    /* Set up the file for nodal/element results */
    float time_val = 0.0;
    if(ex_put_time(exid_vis, 1, &time_val) < 0) {
      Gen_Error(0, "fatal: unable to output time to vis file");
      return 0;
    }

    const char  *var_names[] = {"proc"};
    if(prob->type == NODAL) {
      /* Allocate memory for the nodal values */
      std::vector<float> proc_vals(mesh->num_nodes);

      if(ex_put_variable_param(exid_vis, EX_NODAL, 1) < 0) {
	Gen_Error(0, "fatal: unable to output var params to vis file");
	return 0;
      }

      if(ex_put_variable_names(exid_vis, EX_NODAL, 1, (char**)var_names) < 0) {
	Gen_Error(0, "fatal: unable to output variable name");
	return 0;
      }

      /* Do some problem specific assignment */
      for(size_t ncnt=0; ncnt < mesh->num_nodes; ncnt++)
	proc_vals[ncnt] = lb->vertex2proc[ncnt];

      for(int pcnt=0; pcnt < machine->num_procs; pcnt++) {
	for(auto & elem : lb->bor_nodes[pcnt])
	  proc_vals[elem] = machine->num_procs + 1;
      }

      /* Output the nodal variables */
      if(ex_put_nodal_var(exid_vis, 1, 1, mesh->num_nodes, TOPTR(proc_vals)) < 0) {
	Gen_Error(0, "fatal: unable to output nodal variables");
	return 0;
      }
    }
    else if(prob->type == ELEMENTAL) {
      /* Allocate memory for the element values */
      std::vector<float> proc_vals(mesh->num_elems);

      if(ex_put_variable_param(exid_vis, EX_ELEM_BLOCK, 1) < 0) {
	Gen_Error(0, "fatal: unable to output var params to vis file");
	return 0;
      }

      if(ex_put_variable_names(exid_vis, EX_ELEM_BLOCK, 1, (char**)var_names) < 0) {
	Gen_Error(0, "fatal: unable to output variable name");
	return 0;
      }

      /* Do some problem specific assignment */
      for(int proc=0; proc < machine->num_procs; proc++) {
	for (size_t e = 0; e < lb->int_elems[proc].size(); e++) {
	  size_t ecnt = lb->int_elems[proc][e];
	  proc_vals[ecnt] = proc;
	}

	for (size_t e = 0; e < lb->bor_elems[proc].size(); e++) {
	  size_t ecnt = lb->bor_elems[proc][e];
	  proc_vals[ecnt] = proc;
	}
      }

      /* Output the element variables */
      size_t offset = 0;
      for (size_t i=0; i < mesh->num_el_blks; i++) {
	if(ex_put_var(exid_vis, 1, EX_ELEM_BLOCK, 1, el_blk_ids[i],
		      el_cnt_blk[i], &proc_vals[offset]) < 0) {
	  Gen_Error(0, "fatal: unable to output nodal variables");
	  return 0;
	}
	offset += el_cnt_blk[i];
      }
    }
  }
  return 1;
} /*---------------------------End write_vis()-------------------------------*/
Пример #8
0
int ex_get_side_set_node_list_len(int exoid,
                          int side_set_id,
                          int *side_set_node_list_len)
{
  int i, j, m;
  int  num_side_sets, num_elem_blks, num_df, ndim;
  int tot_num_elem = 0, tot_num_ss_elem = 0; 
  int *elem_blk_ids;
  int *ss_elem_ndx;
  int *side_set_elem_list, *side_set_side_list;
  int elem_ctr; 
  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;

  char errmsg[MAX_ERR_LENGTH];

  exerrval = 0; /* clear error code */

  cdum = 0; /* initialize even though it is not used */

  *side_set_node_list_len = 0; /* default value */
/* 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_len",errmsg,exerrval);
    return(EX_FATAL);
  }

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

  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_len",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_len",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_get_side_set_node_list_len",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_len",errmsg,exerrval);
    return(EX_FATAL);
  }

  if (tot_num_ss_elem == 0) /* NULL side set? */
    return (EX_NOERR); /* return zero */

  /* 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_len",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_len",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_len",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_len",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_len",errmsg,exerrval);
    return (EX_FATAL);
  }

  if (ex_get_elem_blk_ids(exoid, elem_blk_ids))
  {
    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_len",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_len",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_len",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;
    elem_blk_parms[i].elem_blk_id = elem_blk_ids[i];

    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;
      /* 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 = 2;
        else 
          elem_blk_parms[i].num_nodes_per_side = 3;
      }
      else if (ndim == 3)  /* 3d TRIs */
      {   /* set the default number of nodes per side; catch exceptions later */
        if (elem_blk_parms[i].num_nodes_per_elem == 3)
          elem_blk_parms[i].num_nodes_per_side = 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)
        elem_blk_parms[i].num_nodes_per_side = 4;
      else if (elem_blk_parms[i].num_nodes_per_elem == 9)
        elem_blk_parms[i].num_nodes_per_side = 4;
      else if (elem_blk_parms[i].num_nodes_per_elem == 12) /* HEXSHELL */
        elem_blk_parms[i].num_nodes_per_side = 4;
      else if (elem_blk_parms[i].num_nodes_per_elem == 27)
        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_ctr += elem_blk_parms[i].num_elem_in_blk;
    elem_blk_parms[i].elem_ctr = elem_ctr;      /* save elem number max */
  }

/* Walk through element list and keep a running count of the node length */

  *side_set_node_list_len = 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; /* stop because we found the parameters for this element */
    }
    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(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_len",errmsg,EX_MSG);
      return (EX_FATAL);
    }

    /* Update *side_set_node_list_len (which points to next node in chain */

    /* WEDGEs with 3 node sides (side 4 or 5) are special cases */
    if (elem_blk_parms[j].elem_type_val == WEDGE &&
        (side_set_side_list[i] == 4 || side_set_side_list[i] == 5))
    {
      if (elem_blk_parms[j].num_nodes_per_elem == 6)
        *side_set_node_list_len += 3;  /* 3 node side */
      else
        *side_set_node_list_len += 6;  /* 6 node side */
    }
    /* PYRAMIDSs with 3 node sides (sides 1,2,3,4) are also special */
    else if (elem_blk_parms[j].elem_type_val == PYRAMID &&
             (side_set_side_list[i] < 5))
    {
      if (elem_blk_parms[j].num_nodes_per_elem == 5)
        *side_set_node_list_len += 3;  /* 3 node side */
      else
        *side_set_node_list_len += 6;  /* 6 node side */
    }
    /* side numbers 3,4,5,6 for SHELLs are also special */
    else if (elem_blk_parms[j].elem_type_val == SHELL &&
        (side_set_side_list[i] > 2 ))
    {
      if (elem_blk_parms[j].num_nodes_per_elem == 4)
        *side_set_node_list_len += 2;  /* 2 node side */
      else
        *side_set_node_list_len += 3;  /* 3 node side */
    }
    /* sides 3, 4, and 5 of 3d TRIs are special cases */
    else if (elem_blk_parms[j].elem_type_val == TRIANGLE &&
             ndim == 3 &&
             side_set_side_list[i] > 2 )
    {
      if (elem_blk_parms[j].num_nodes_per_elem == 3)  /* 3-node TRI */
        *side_set_node_list_len += 2;  /* 2 node side */
      else  /* 6-node TRI */
        *side_set_node_list_len += 3;  /* 3 node side */
    }
    else if (elem_blk_parms[j].elem_type_val == UNK)
    {
      exerrval = EX_BADPARAM;
      sprintf(errmsg,
             "Error: %s in elem block %d is an unsupported element type",
              elem_blk_parms[i].elem_type, elem_blk_parms[i].elem_blk_id);
      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_len",errmsg,EX_MSG);
      return (EX_FATAL);
    }
    else /* all other element types */
      *side_set_node_list_len += elem_blk_parms[j].num_nodes_per_side;
  }

  /* All done: release element block ids array,
     element block parameters array, and side set element index array */
  free(elem_blk_ids);
  free(elem_blk_parms);
  free(ss_elem_ndx);
  free(side_set_side_list);
  free(side_set_elem_list);

  return(EX_NOERR);
}
Пример #9
0
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);
}
Пример #10
0
/*@
  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);
}
Пример #11
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;
}
Пример #12
0
int ex_put_all_var_param (int   exoid,
			  int   num_g,
			  int   num_n,
			  int   num_e,
			  int  *elem_var_tab,
			  int   num_m,
			  int  *nset_var_tab,
			  int   num_s,
			  int  *sset_var_tab)
{
  int in_define = 0;
  int time_dim, num_nod_dim, dimid, iresult;
  long num_elem_blk, num_nset, num_sset;
  int numelblkdim, numelvardim, numnsetdim, nsetvardim, numssetdim, ssetvardim;
  int i;

  int eblk_varid, nset_varid, sset_varid;
  
  int *eblk_ids = 0;
  int *nset_ids = 0;
  int *sset_ids = 0;

  nclong *eblk_stat = 0;
  nclong *nset_stat = 0;
  nclong *sset_stat = 0;
  
  int dims[3];
  char errmsg[MAX_ERR_LENGTH];
  const char* routine = "ex_put_all_var_param";

  exerrval = 0; /* clear error code */

  /* inquire previously defined dimensions  */

  if ((time_dim = ncdimid (exoid, DIM_TIME)) == -1) {
    exerrval = ncerr;
    sprintf(errmsg,
	    "Error: failed to locate time dimension in file id %d", exoid);
    ex_err("ex_put_all_var_param",errmsg,exerrval);
    goto error_ret;
  }

  if ((num_nod_dim = ncdimid (exoid, DIM_NUM_NODES)) == -1) {
    if (num_n > 0) {
      exerrval = ncerr;
      sprintf(errmsg,
	      "Error: failed to locate number of nodes in file id %d",
	      exoid);
      ex_err("ex_put_all_var_param",errmsg,exerrval);
      goto error_ret;
    }
  }

  /* Check this now so we can use it later without checking for errors */
  if (ncdimid (exoid, DIM_STR) < 0) {
    exerrval = ncerr;
    sprintf(errmsg,
	    "Error: failed to get string length in file id %d",exoid);
    ex_err("ex_put_all_var_param",errmsg,exerrval);
    goto error_ret;
  }

  if (num_e > 0) {
    numelblkdim = ex_get_dimension(exoid, DIM_NUM_EL_BLK, "element blocks", &num_elem_blk, routine);
    if (numelblkdim == -1)
      goto error_ret;
    
    /* get element block IDs */
    if (!(eblk_ids = static_cast<int*>(malloc(num_elem_blk*sizeof(int))))) {
      exerrval = EX_MEMFAIL;
      sprintf(errmsg,
	      "Error: failed to allocate memory for element block id array for file id %d",
	      exoid);
      ex_err("ex_put_all_var_param",errmsg,exerrval);
      goto error_ret;
    }
    ex_get_elem_blk_ids (exoid, eblk_ids);

    /* Get element block status array for later use (allocates memory) */
    eblk_stat = get_status_array(exoid, num_elem_blk, VAR_STAT_EL_BLK, "element block");
    if (eblk_stat == NULL) {
      goto error_ret;
    }
  }

  if (num_m > 0) {
    numnsetdim = ex_get_dimension(exoid, DIM_NUM_NS, "nodesets", &num_nset, routine);
    if (numnsetdim == -1)
      goto error_ret;
    
    /* get nodeset IDs */
    if (!(nset_ids = static_cast<int*>(malloc(num_nset*sizeof(int))))) {
      exerrval = EX_MEMFAIL;
      sprintf(errmsg,
	      "Error: failed to allocate memory for nodeset id array for file id %d",
	      exoid);
      ex_err("ex_put_all_var_param",errmsg,exerrval);
      goto error_ret;
    }
    ex_get_node_set_ids (exoid, nset_ids);

    /* Get nodeset status array for later use (allocates memory) */
    nset_stat = get_status_array(exoid, num_nset, VAR_NS_STAT, "nodeset");
    if (nset_stat == NULL) {
      goto error_ret;
    }
  }

  if (num_s > 0) {
    numssetdim = ex_get_dimension(exoid, DIM_NUM_SS, "sidesets", &num_sset, routine);
    if (numssetdim == -1)
      goto error_ret;
    
    /* get sideset IDs */
    if (!(sset_ids = static_cast<int*>(malloc(num_sset*sizeof(int))))) {
      exerrval = EX_MEMFAIL;
      sprintf(errmsg,
	      "Error: failed to allocate memory for sideset id array for file id %d",
	      exoid);
      ex_err("ex_put_all_var_param",errmsg,exerrval);
      goto error_ret;
    }
    ex_get_side_set_ids (exoid, sset_ids);

    /* Get sideset status array for later use (allocates memory) */
    sset_stat = get_status_array(exoid, num_sset, VAR_SS_STAT, "sideset");
    if (sset_stat == NULL) {
      goto error_ret;
    }
  }

  /* put file into define mode  */
  if (ncredef (exoid) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
              "Error: failed to put file id %d into define mode", exoid);
      ex_err("ex_put_all_var_param",errmsg,exerrval);
      goto error_ret;
    }
  in_define = 1;

  /* define dimensions and variables */

  if (num_g > 0) 
    {
      dimid = define_dimension(exoid, DIM_NUM_GLO_VAR, num_g, "global");
      if (dimid == -1) goto error_ret;

      
      dims[0] = time_dim;
      dims[1] = dimid;
      if ((ncvardef (exoid, VAR_GLO_VAR, 
                     nc_flt_code(exoid), 2, dims)) == -1)
        {
          exerrval = ncerr;
          sprintf(errmsg,
                  "Error: failed to define global variables in file id %d",
                  exoid);
          ex_err("ex_put_all_var_param",errmsg,exerrval);
          goto error_ret;          /* exit define mode and return */
        }

      /* Now define global variable name variable */
      if (define_variable_name_variable(exoid, VAR_NAME_GLO_VAR, dimid, "global") == -1)
	goto error_ret;
    }

  if (num_n > 0) 
    {
      /*
       * There are two ways to store the nodal variables. The old way *
       * was a blob (#times,#vars,#nodes), but that was exceeding the
       * netcdf maximum dataset size for large models. The new way is
       * to store #vars separate datasets each of size (#times,#nodes)
       *
       * We want this routine to be capable of storing both formats
       * based on some external flag.  Since the storage format of the
       * coordinates have also been changed, we key off of their
       * storage type to decide which method to use for nodal
       * variables. If the variable 'coord' is defined, then store old
       * way; otherwise store new.
       */
      dimid = define_dimension(exoid, DIM_NUM_NOD_VAR, num_n, "nodal");
      if (dimid == -1) goto error_ret;

      if (ex_large_model(exoid) == 0) { /* Old way */
        dims[0] = time_dim;
        dims[1] = dimid;
        dims[2] = num_nod_dim;
        if ((ncvardef (exoid, VAR_NOD_VAR,
                       nc_flt_code(exoid), 3, dims)) == -1)
          {
            exerrval = ncerr;
            sprintf(errmsg,
                    "Error: failed to define nodal variables in file id %d",
                    exoid);
            ex_err("ex_put_all_var_param",errmsg,exerrval);
            goto error_ret;          /* exit define mode and return */
          }
      } else { /* Store new way */
        for (i = 1; i <= num_n; i++) {
          dims[0] = time_dim;
          dims[1] = num_nod_dim;
          if ((ncvardef (exoid, VAR_NOD_VAR_NEW(i),
                         nc_flt_code(exoid), 2, dims)) == -1)
            {
              exerrval = ncerr;
              sprintf(errmsg,
                      "Error: failed to define nodal variable %d in file id %d",
                      i, exoid);
              ex_err("ex_put_var_param",errmsg,exerrval);
              goto error_ret;          /* exit define mode and return */
            }
        }
      }

      /* Now define nodal variable name variable */
      if (define_variable_name_variable(exoid, VAR_NAME_NOD_VAR, dimid, "nodal") == -1)
	goto error_ret;
    }

  if (num_e > 0) {
    numelvardim = define_dimension(exoid, DIM_NUM_ELE_VAR, num_e, "element");
    if (numelvardim == -1) goto error_ret;

    /* Now define element variable name variable */
    if (define_variable_name_variable(exoid, VAR_NAME_ELE_VAR, numelvardim, "element") == -1)
      goto error_ret;

    if (define_truth_table('e', exoid, num_elem_blk, num_e, elem_var_tab, eblk_stat, eblk_ids, "element block") == -1)
      goto error_ret;

    eblk_stat = static_cast<nclong*>(safe_free (eblk_stat));
    eblk_ids  = static_cast<int*>(   safe_free (eblk_ids));

    /* create a variable array in which to store the element variable truth
     * table
     */

    dims[0] = numelblkdim;
    dims[1] = numelvardim;

    if ((eblk_varid = ncvardef (exoid, VAR_ELEM_TAB, NC_LONG, 2, dims)) == -1) {
      exerrval = ncerr;
      sprintf(errmsg,
	      "Error: failed to define element variable truth table in file id %d",
	      exoid);
      ex_err("ex_put_all_var_param",errmsg,exerrval);
      goto error_ret;          /* exit define mode and return */
    }

  }

  if (num_m > 0) {
    nsetvardim = define_dimension(exoid, DIM_NUM_NSET_VAR, num_m, "nodeset");
    if (nsetvardim == -1) goto error_ret;

    /* Now define nodeset variable name variable */
    if (define_variable_name_variable(exoid, VAR_NAME_NSET_VAR, nsetvardim, "nodeset") == -1)
      goto error_ret;

    if (define_truth_table('m', exoid, num_nset, num_m, nset_var_tab, nset_stat, nset_ids, "nodeset") == -1)
      goto error_ret;

    nset_stat = static_cast<nclong*>(safe_free (nset_stat));
    nset_ids  = static_cast<int*>(safe_free (nset_ids));

    /* create a variable array in which to store the truth table
     */

    dims[0] = numnsetdim;
    dims[1] = nsetvardim;

    if ((nset_varid = ncvardef (exoid, VAR_NSET_TAB, NC_LONG, 2, dims)) == -1) {
      exerrval = ncerr;
      sprintf(errmsg,
	      "Error: failed to define nodeset variable truth table in file id %d",
	      exoid);
      ex_err("ex_put_all_var_param",errmsg,exerrval);
      goto error_ret;          /* exit define mode and return */
    }
  }

  if (num_s > 0) {
    ssetvardim = define_dimension(exoid, DIM_NUM_SSET_VAR, num_s, "sideset");
    if (ssetvardim == -1) goto error_ret;

    /* Now define sideset variable name variable */
    if (define_variable_name_variable(exoid, VAR_NAME_SSET_VAR, ssetvardim, "sideset") == -1)
      goto error_ret;

    if (define_truth_table('s', exoid, num_sset, num_s, sset_var_tab, sset_stat, sset_ids, "sideset") == -1)
      goto error_ret;
      
    sset_stat = static_cast<nclong*>(safe_free (sset_stat));
    sset_ids  = static_cast<int*>(safe_free (sset_ids));

    /* create a variable array in which to store the truth table
     */

    dims[0] = numssetdim;
    dims[1] = ssetvardim;

    if ((sset_varid = ncvardef (exoid, VAR_SSET_TAB, NC_LONG, 2, dims)) == -1) {
      exerrval = ncerr;
      sprintf(errmsg,
	      "Error: failed to define sideset variable truth table in file id %d",
	      exoid);
      ex_err("ex_put_all_var_param",errmsg,exerrval);
      goto error_ret;          /* exit define mode and return */
    }
  }

  /* leave define mode  */

  in_define = 0;
  if (ncendef (exoid) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
              "Error: failed to complete definition in file id %d",
              exoid);
      ex_err("ex_put_all_var_param",errmsg,exerrval);
      goto error_ret;
    }

  /* write out the variable truth tables */
  if (num_e > 0) {
    iresult = put_truth_table(exoid, num_elem_blk, num_e, eblk_varid, elem_var_tab, "element");
    if (iresult == -1) goto error_ret;
  }

  if (num_m > 0) {
    iresult = put_truth_table(exoid, num_nset, num_m, nset_varid, nset_var_tab, "nodeset");
    if (iresult == -1) goto error_ret;
  }

  if (num_s > 0) {
    iresult = put_truth_table(exoid, num_sset, num_s, sset_varid, sset_var_tab, "sideset");
    if (iresult == -1) goto error_ret;
  }

  return(EX_NOERR);
  
  /* Fatal error: exit definition mode and return */
 error_ret:
  if (in_define == 1) {
    if (ncendef (exoid) == -1)     /* exit define mode */
      {
	sprintf(errmsg,
		"Error: failed to complete definition for file id %d",
		exoid);
	ex_err("ex_put_all_var_param",errmsg,exerrval);
      }
  }
  safe_free(eblk_ids);
  safe_free(nset_ids);
  safe_free(sset_ids);

  safe_free(eblk_stat);
  safe_free(nset_stat);
  safe_free(sset_stat);
  return(EX_FATAL);
}
Пример #13
0
int main (int argc, char **argv)
{
  int exoid, num_dim, num_nodes, num_elem, num_elem_blk;
  int num_elem_in_block[10], num_nodes_per_elem[10], num_attr[10];
  int num_node_sets, num_side_sets, error;
  int i, j, *connect;
  int ebids[10], ids[10];
  int CPU_word_size,IO_word_size;
  char title[MAX_LINE_LENGTH+1], elem_type[MAX_STR_LENGTH+1];

  float version;
  float *attrib;
  float x[100], y[100], z[100];
  char *coord_names[3];

   ex_opts (EX_VERBOSE | EX_ABORT);

  /* Specify compute and i/o word size */

  CPU_word_size = 0;                   /* sizeof(float) */
  IO_word_size = 4;                    /* (4 bytes) */

  /* create EXODUS II file */

  exoid = ex_create ("test.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 */
  /* initialize file with parameters */

  num_dim = 3;
  num_nodes = 19;
  num_elem = 12;;
  num_elem_blk = 1;
  num_node_sets = 0;
  num_side_sets = 0;

  error = ex_put_init (exoid, "This is testwt1", num_dim, num_nodes, num_elem,
		       num_elem_blk, num_node_sets, num_side_sets);
  assert(error == 0);

  /* write nodal coordinates values and names to database */

  /* Quad #1 */
  x[0]  = 1.0000000E+00;
  x[1]  = 5.0000000E-01;
  x[2]  = 1.0000000E+00;
  x[3]  = 1.0000000E+00;
  x[4]  = 7.5000000E-01;
  x[5]  = 5.0000000E-01;
  x[6]  = 1.0000000E+00;
  x[7]  = 7.5000000E-01;
  x[8]  = 1.0000000E+00;
  x[9]  = 5.0000000E-01;
  x[10] = 5.0000000E-01;
  x[11] = 5.0000000E-01;
  x[12] = 1.0000000E+00;
  x[13] = 1.0000000E+00;
  x[14] = 7.5000000E-01;
  x[15] = 7.5000000E-01;
  x[16] = 1.0000000E+00;
  x[17] = 7.5000000E-01;
  x[18] = 1.0000000E+00;

  y[0]  =  5.0000000E-01;
  y[1]  =  1.0000000E+00;
  y[2]  =  1.0000000E+00;
  y[3]  =  7.5000000E-01;
  y[4]  =  1.0000000E+00;
  y[5]  =  5.0000000E-01;
  y[6]  =  5.0000000E-01;
  y[7]  =  5.0000000E-01;
  y[8]  =  5.0000000E-01;
  y[9]  =  1.0000000E+00;
  y[10] =  7.5000000E-01;
  y[11] =  1.0000000E+00;
  y[12] =  1.0000000E+00;
  y[13] =  7.5000000E-01;
  y[14] =  1.0000000E+00;
  y[15] =  7.5000000E-01;
  y[16] =  1.0000000E+00;
  y[17] =  1.0000000E+00;
  y[18] =  7.5000000E-01;

  z[0]  = 5.0000000E-01;
  z[1]  = 5.0000000E-01;
  z[2]  = 5.0000000E-01;
  z[3]  = 5.0000000E-01;
  z[4]  = 5.0000000E-01;
  z[5]  = 1.0000000E+00;
  z[6]  = 1.0000000E+00;
  z[7]  = 1.0000000E+00;
  z[8]  = 7.5000000E-01;
  z[9]  = 1.0000000E+00;
  z[10] = 1.0000000E+00;
  z[11] = 7.5000000E-01;
  z[12] = 1.0000000E+00;
  z[13] = 1.0000000E+00;
  z[14] = 1.0000000E+00;
  z[15] = 1.0000000E+00;
  z[16] = 7.5000000E-01;
  z[17] = 7.5000000E-01;
  z[18] = 7.5000000E-01;

  error = ex_put_coord (exoid, x, y, z);
  assert(error == 0);

  coord_names[0] = "xcoor";
  coord_names[1] = "ycoor";
  coord_names[2] = "zcoor";

  error = ex_put_coord_names (exoid, coord_names);
  assert(error == 0);

  /* write element block parameters */
  num_elem_in_block[0] = 12;
  num_nodes_per_elem[0] = 4;
  ebids[0] = 10;
  num_attr[0] = 3;

  error = ex_put_elem_block (exoid, ebids[0], "quad", num_elem_in_block[0],
			     num_nodes_per_elem[0], num_attr[0]);
  assert(error == 0);

  /* write element connectivity */
  connect = (int *) calloc(num_elem_in_block[0] * num_nodes_per_elem[0], sizeof(int));

  connect[ 0] =  1;
  connect[ 1] =  4;
  connect[ 2] = 19;
  connect[ 3] =  9;
  connect[ 4] =  4;
  connect[ 5] =  3;
  connect[ 6] = 17;
  connect[ 7] = 19;
  connect[ 8] =  3;
  connect[ 9] =  5;
  connect[10] = 18;
  connect[11] = 17;
  connect[12] =  5;
  connect[13] =  2;
  connect[14] = 12;
  connect[15] = 18;
  connect[16] =  9;
  connect[17] = 19;
  connect[18] = 14;
  connect[19] =  7;
  connect[20] =  7;
  connect[21] = 14;
  connect[22] = 16;
  connect[23] =  8;
  connect[24] = 19;
  connect[25] = 17;
  connect[26] = 13;
  connect[27] = 14;
  connect[28] = 17;
  connect[29] = 18;
  connect[30] = 15;
  connect[31] = 13;
  connect[32] = 14;
  connect[33] = 13;
  connect[34] = 15;
  connect[35] = 16;
  connect[36] =  8;
  connect[37] = 16;
  connect[38] = 11;
  connect[39] =  6;
  connect[40] = 18;
  connect[41] = 12;
  connect[42] = 10;
  connect[43] = 15;
  connect[44] = 16;
  connect[45] = 15;
  connect[46] = 10;
  connect[47] = 11;

  error = ex_put_elem_conn (exoid, ebids[0], connect);
  assert(error == 0);
  free (connect);

  /* write element block attributes  (3 per block) */
  attrib = (float *) calloc(num_elem_in_block[0] * num_attr[0], sizeof(float));

#if 0
  {
    k = 0;
    for (i=0; i < num_elem_in_block[0]; i++) {
      for (j = 0; j < num_attr[0]; j++) {
	attrib[k++] = 10*(i+1) + j+1;
      }
    }
  }

  error = ex_put_elem_attr (exoid, ebids[0], &attrib[0]);
  assert(error == 0);
#else
  {
    for (j = 0; j < num_attr[0]; j++) {
      for (i=0; i < num_elem_in_block[0]; i++) {
	attrib[i] = 10*(i+1) + j+1;
      }
      error = ex_put_one_elem_attr (exoid, ebids[0], j+1, &attrib[0]);
      assert(error == 0);
    }
  }
#endif
  free(attrib);

  /* close the EXODUS files
   */
  error = ex_close (exoid);
  assert(error == 0);


  /* Reopen the file and read the attributes to see if they were written correctly */
  CPU_word_size = 0;                    /* sizeof(float) */
  IO_word_size = 0;                     /* use what is stored in file */


  /* 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 */

  assert(exoid >= 0);
  if (exoid < 0) exit(1);

  error = ex_get_init (exoid, title, &num_dim, &num_nodes, &num_elem,
                       &num_elem_blk, &num_node_sets, &num_side_sets);

  assert(error == 0);

  if (num_elem_blk > 0) {
    error = ex_get_elem_blk_ids (exoid, ids);
    assert(error == 0);
    
    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]));
	assert(error == 0);
      }
     
    /* read element block attributes */

    attrib = (float *) calloc(num_elem_in_block[0],sizeof(float));
    for (j = 0; j < num_attr[0]; j++) {
      error = ex_get_one_elem_attr (exoid, ids[0], j+1, &attrib[0]);
      assert(error == 0);
	
      if (error == 0) {
	for (i=0; i < num_elem_in_block[0]; i++) {
	  assert(attrib[i] == 10*(i+1) + j+1);	  }
      }
    }
    free (attrib);
  }
  error = ex_close (exoid);
  assert(error == 0);
  return 0;
}
Пример #14
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);
  }
Пример #15
0
/*
//  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);
    }
  }
}
Пример #16
0
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()-------------------------------*/
Пример #17
0
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_get_side_set_node_list_len(int exoid,
				  ex_entity_id side_set_id,
				  void_int *side_set_node_list_len)
{
  size_t i, j;
  size_t m;
  int64_t num_side_sets, num_elem_blks, num_df, ndim;
  size_t list_len = 0;
  int64_t tot_num_elem = 0, tot_num_ss_elem = 0; 
  void_int *elem_blk_ids;
  int *ss_elem_ndx = NULL;
  int64_t *ss_elem_ndx_64 = NULL;
  
  void_int *side_set_elem_list;
  void_int *side_set_side_list;
  int elem_ctr; 
  int status;
  
  struct elem_blk_parm  *elem_blk_parms;

  char errmsg[MAX_ERR_LENGTH];

  exerrval = 0; /* clear error code */

    if (ex_int64_status(exoid) & EX_BULK_INT64_API)
      *(int64_t*)side_set_node_list_len = 0; /* default value */
    else
      *(int*)side_set_node_list_len = 0; /* default value */
      
  /* first check if any side sets are specified */
  /* inquire how many side sets have been stored */

  /* get the dimensionality of the coordinates;  this is necessary to
     distinguish between 2d TRIs and 3d TRIs */

  ndim = ex_inquire_int(exoid, EX_INQ_DIM);
  if (ndim < 0)  {
    sprintf(errmsg,
           "Error: failed to get dimensionality in file id %d",exoid);
    ex_err("ex_get_side_set_node_list_len",errmsg,exerrval);
    return(EX_FATAL);
  }

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

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

  num_side_sets = ex_inquire_int(exoid, EX_INQ_SIDE_SETS);
  if (num_side_sets < 0) {
    sprintf(errmsg,
           "Error: failed to get number of side sets in file id %d",exoid);
    ex_err("ex_get_side_set_node_list_len",errmsg,exerrval);
    return(EX_FATAL);
  }

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

  /* First determine the  # of elements in the side set*/
  if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
    status = ex_get_side_set_param(exoid,side_set_id,&tot_num_ss_elem,&num_df);
  } else {
    int tot;
    int df;
    status = ex_get_side_set_param(exoid,side_set_id,&tot,&df);
    tot_num_ss_elem = tot;
    num_df = df;
  }

  if (status != NC_NOERR) {
    sprintf(errmsg,
         "Error: failed to get number of elements in side set %"PRId64" in file id %d",
            side_set_id, exoid);
    ex_err("ex_get_side_set_node_list_len",errmsg,exerrval);
    return(EX_FATAL);
  }

  if (tot_num_ss_elem == 0) /* NULL side set? */
    return (EX_NOERR); /* return zero */

  /* Minor optimization/kluge -- If num_df is nonzero, or 1 per face
     then assume that it matches the number of nodes in the sideset... */
  if (num_df > 0 && num_df != tot_num_ss_elem) {
    if (ex_int64_status(exoid) & EX_BULK_INT64_API)
      *(int64_t*)side_set_node_list_len = num_df;
    else
      *(int*)side_set_node_list_len = num_df;
    return(EX_NOERR);
  }

  /* Allocate space for the side set element list */
  {
    int int_size = sizeof(int);
    if (ex_int64_status(exoid) & EX_BULK_INT64_API)
      int_size = sizeof(int64_t);
    if (!(side_set_elem_list=malloc(tot_num_ss_elem*int_size))) {
      exerrval = EX_MEMFAIL;
      sprintf(errmsg,
	      "Error: failed to allocate space for side set element list for file id %d",
	      exoid);
      ex_err("ex_get_side_set_node_list_len",errmsg,exerrval);
      return (EX_FATAL);
    }

    /* Allocate space for the side set side list */
    if (!(side_set_side_list=malloc(tot_num_ss_elem*int_size))) {
      safe_free(side_set_elem_list);
      exerrval = EX_MEMFAIL;
      sprintf(errmsg,
	      "Error: failed to allocate space for side set side list for file id %d",
	      exoid);
      ex_err("ex_get_side_set_node_list_len",errmsg,exerrval);
      return (EX_FATAL);
    }

    if (ex_get_side_set(exoid, side_set_id, 
			side_set_elem_list, side_set_side_list) != NC_NOERR) {
      safe_free(side_set_elem_list);
      safe_free(side_set_side_list);
      sprintf(errmsg,
	      "Error: failed to get side set %"PRId64" in file id %d",
	      side_set_id, exoid);
      ex_err("ex_get_side_set_node_list_len",errmsg,exerrval);
      return (EX_FATAL);
    }
    
    /* Allocate space for the ss element index array */
    if (int_size == sizeof(int64_t)) {
      ss_elem_ndx_64=malloc(tot_num_ss_elem*int_size);
    } else {
      ss_elem_ndx   =malloc(tot_num_ss_elem*int_size);
    }

    if (ss_elem_ndx_64==NULL && ss_elem_ndx == NULL) {
      safe_free(side_set_elem_list);
      safe_free(side_set_side_list);
      exerrval = EX_MEMFAIL;
      sprintf(errmsg,
	      "Error: failed to allocate space for side set elem sort array for file id %d",
	      exoid);
      ex_err("ex_get_side_set_node_list_len",errmsg,exerrval);
      return (EX_FATAL);
    }
  }

  /* Sort side set element list into index array  - non-destructive */
  if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
    for (i=0;i<tot_num_ss_elem;i++)
      ss_elem_ndx_64[i] = i; /* init index array to current position */
    ex_iqsort64(side_set_elem_list, ss_elem_ndx_64,tot_num_ss_elem);
  } else {
    for (i=0;i<tot_num_ss_elem;i++)
      ss_elem_ndx[i] = i; /* init index array to current position */
    ex_iqsort(side_set_elem_list, ss_elem_ndx,tot_num_ss_elem);
  }


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

    if (!(elem_blk_ids=malloc(num_elem_blks*int_size))) {
      exerrval = EX_MEMFAIL;
      safe_free(ss_elem_ndx);
      safe_free(ss_elem_ndx_64);
      safe_free(side_set_side_list);
      safe_free(side_set_elem_list);
      sprintf(errmsg,
	      "Error: failed to allocate space for element block ids for file id %d",
	      exoid);
      ex_err("ex_get_side_set_node_list_len",errmsg,exerrval);
      return (EX_FATAL);
    }
  }
  
  if (ex_get_elem_blk_ids(exoid, elem_blk_ids)) {
    safe_free(elem_blk_ids);
    safe_free(ss_elem_ndx);
    safe_free(ss_elem_ndx_64);
    safe_free(side_set_side_list);
    safe_free(side_set_elem_list);
    sprintf(errmsg,
	    "Error: failed to get element block ids in file id %d",
            exoid);
    ex_err("ex_get_side_set_node_list_len",errmsg,EX_MSG);
    return(EX_FATAL);
  } 

  /* Allocate space for the element block params */
  if (!(elem_blk_parms=malloc(num_elem_blks*sizeof(struct elem_blk_parm)))) {
    safe_free(elem_blk_ids);
    safe_free(ss_elem_ndx);
    safe_free(ss_elem_ndx_64);
    safe_free(side_set_side_list);
    safe_free(side_set_elem_list);
    exerrval = EX_MEMFAIL;
    sprintf(errmsg,
      "Error: failed to allocate space for element block params for file id %d",
            exoid);
    ex_err("ex_get_side_set_node_list_len",errmsg,exerrval);
    return (EX_FATAL);
  }

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

    /* read in an element block parameter */
    if ((ex_get_block_param (exoid, &block)) != NC_NOERR) {
      safe_free(elem_blk_parms);
      safe_free(elem_blk_ids);
      safe_free(ss_elem_ndx);
      safe_free(ss_elem_ndx_64);
      safe_free(side_set_side_list);
      safe_free(side_set_elem_list);
      sprintf(errmsg,
             "Error: failed to get element block %"PRId64" parameters in file id %d",
              block.id, exoid);
      ex_err("ex_get_side_set_node_list_len",errmsg,EX_MSG);
      return(EX_FATAL);
    }

    elem_blk_parms[i].num_elem_in_blk = block.num_entry;
    elem_blk_parms[i].num_nodes_per_elem = block.num_nodes_per_entry;
    elem_blk_parms[i].num_attr = block.num_attribute;
    elem_blk_parms[i].elem_blk_id = block.id;

    for (m=0; m < strlen(block.topology); m++) {
      elem_blk_parms[i].elem_type[m] = toupper(block.topology[m]);
    }
    elem_blk_parms[i].elem_type[m] = '\0';

    if (strncmp(elem_blk_parms[i].elem_type,"CIRCLE",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = EX_EL_CIRCLE;
      /* set side set node stride */
        elem_blk_parms[i].num_nodes_per_side[0] = 1;
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"SPHERE",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = EX_EL_SPHERE;
      /* set side set node stride */
        elem_blk_parms[i].num_nodes_per_side[0] = 1;
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"QUAD",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = EX_EL_QUAD;
      /* determine side set node stride */
      if (elem_blk_parms[i].num_nodes_per_elem == 4)
        elem_blk_parms[i].num_nodes_per_side[0] = 2;
      else if (elem_blk_parms[i].num_nodes_per_elem == 5)
        elem_blk_parms[i].num_nodes_per_side[0] = 2;
      else 
        elem_blk_parms[i].num_nodes_per_side[0] = 3;
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"TRIANGLE",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = EX_EL_TRIANGLE;
      /* determine side set node stride */
      if (ndim == 2) /* 2d TRIs */
      {
        if (elem_blk_parms[i].num_nodes_per_elem == 3)
          elem_blk_parms[i].num_nodes_per_side[0] = 2;
        else 
          elem_blk_parms[i].num_nodes_per_side[0] = 3;
      }
      else if (ndim == 3)  /* 3d TRIs */
      {   /* set the default number of nodes per side; catch exceptions later */
        if (elem_blk_parms[i].num_nodes_per_elem == 3)
          elem_blk_parms[i].num_nodes_per_side[0] = 3;
        else 
          elem_blk_parms[i].num_nodes_per_side[0] = 6;
      }
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"SHELL",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = EX_EL_SHELL;
      /* determine side set node stride */
      if (elem_blk_parms[i].num_nodes_per_elem == 2) /* KLUDGE for 2D Shells*/
        elem_blk_parms[i].num_nodes_per_side[0] = 2;
      else if (elem_blk_parms[i].num_nodes_per_elem == 4)
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
      else
        elem_blk_parms[i].num_nodes_per_side[0] = 8;
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"HEX",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = EX_EL_HEX;
      /* determine side set node stride */
      if (elem_blk_parms[i].num_nodes_per_elem == 8)
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
      else if (elem_blk_parms[i].num_nodes_per_elem == 9)
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
      else if (elem_blk_parms[i].num_nodes_per_elem == 12) /* HEXSHELL */
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
      else if (elem_blk_parms[i].num_nodes_per_elem == 27)
        elem_blk_parms[i].num_nodes_per_side[0] = 9;
      else
        elem_blk_parms[i].num_nodes_per_side[0] = 8;
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"TETRA",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = EX_EL_TETRA;
      /* determine side set node stride */
      if (elem_blk_parms[i].num_nodes_per_elem == 4)
        elem_blk_parms[i].num_nodes_per_side[0] = 3;
      else if (elem_blk_parms[i].num_nodes_per_elem == 8)
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
      else
        elem_blk_parms[i].num_nodes_per_side[0] = 6;
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"WEDGE",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = EX_EL_WEDGE;
      /* determine side set node stride */
      if (elem_blk_parms[i].num_nodes_per_elem == 6)
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
      else
        elem_blk_parms[i].num_nodes_per_side[0] = 8;
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"PYRAMID",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = EX_EL_PYRAMID;
      /* determine side set node stride */
      if (elem_blk_parms[i].num_nodes_per_elem == 5)
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
      else
        elem_blk_parms[i].num_nodes_per_side[0] = 8;
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"BEAM",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = EX_EL_BEAM;
      /* determine side set node stride */
      if (elem_blk_parms[i].num_nodes_per_elem == 2)
        elem_blk_parms[i].num_nodes_per_side[0] = 2;
      else 
        elem_blk_parms[i].num_nodes_per_side[0] = 3;
    }
    else if ( (strncmp(elem_blk_parms[i].elem_type,"TRUSS",3) == 0) ||
              (strncmp(elem_blk_parms[i].elem_type,"BAR",3) == 0)  ||
              (strncmp(elem_blk_parms[i].elem_type,"EDGE",3) == 0))
    {
      elem_blk_parms[i].elem_type_val = EX_EL_TRUSS;
      /* determine side set node stride */
      if (elem_blk_parms[i].num_nodes_per_elem == 2)
        elem_blk_parms[i].num_nodes_per_side[0] = 2;
      else 
        elem_blk_parms[i].num_nodes_per_side[0] = 3;
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"NULL",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = EX_EL_NULL_ELEMENT;
      elem_blk_parms[i].num_nodes_per_side[0] = 0;
      elem_blk_parms[i].num_elem_in_blk = 0;
    }
    else
    { /* unsupported element type; no problem if no sides specified for
         this element block */
      elem_blk_parms[i].elem_type_val = EX_EL_UNK;
      elem_blk_parms[i].num_nodes_per_side[0] = 0;
    }

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

/* Walk through element list and keep a running count of the node length */

  list_len = 0;
  for (i=0;i<tot_num_ss_elem;i++)
  {
    size_t elem;
    size_t side;
    if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
      elem = ((int64_t*)side_set_elem_list)[i];
      side = ((int64_t*)side_set_side_list)[i];
    } else {
      elem = ((int*)side_set_elem_list)[i];
      side = ((int*)side_set_side_list)[i];
    }

    for (j=0; j<num_elem_blks; j++)
    {
      if (elem_blk_parms[j].elem_type_val != EX_EL_NULL_ELEMENT)
        if (elem <= elem_blk_parms[j].elem_ctr)
          break; /* stop because we found the parameters for this element */
    }
    if (j >= num_elem_blks)
    {
      exerrval = EX_BADPARAM;
      sprintf(errmsg,
             "Error: Invalid element number %"ST_ZU" found in side set %"PRId64" in file %d",
              elem, side_set_id, exoid);
      safe_free(elem_blk_parms);
      safe_free(elem_blk_ids);
      safe_free(ss_elem_ndx);
      safe_free(ss_elem_ndx_64);
      safe_free(side_set_side_list);
      safe_free(side_set_elem_list);
      ex_err("ex_get_side_set_node_list_len",errmsg,EX_MSG);
      return (EX_FATAL);
    }

    /* Update *side_set_node_list_len (which points to next node in chain */

    /* WEDGEs with 3 node sides (side 4 or 5) are special cases */
    if (elem_blk_parms[j].elem_type_val == EX_EL_WEDGE &&
        (side == 4 || side == 5))
    {
      if (elem_blk_parms[j].num_nodes_per_elem == 6)
        list_len += 3;  /* 3 node side */
      else
        list_len += 6;  /* 6 node side */
    }
    /* PYRAMIDSs with 3 node sides (sides 1,2,3,4) are also special */
    else if (elem_blk_parms[j].elem_type_val == EX_EL_PYRAMID &&
             (side < 5))
    {
      if (elem_blk_parms[j].num_nodes_per_elem == 5)
        list_len += 3;  /* 3 node side */
      else
        list_len += 6;  /* 6 node side */
    }
    /* side numbers 3,4,5,6 for SHELLs are also special */
    else if (elem_blk_parms[j].elem_type_val == EX_EL_SHELL &&
        (side > 2 ))
    {
      if (elem_blk_parms[j].num_nodes_per_elem == 4)
        list_len += 2;  /* 2 node side */
      else
        list_len += 3;  /* 3 node side */
    }
    /* sides 3, 4, and 5 of 3d TRIs are special cases */
    else if (elem_blk_parms[j].elem_type_val == EX_EL_TRIANGLE &&
             ndim == 3 && side > 2 )
    {
      if (elem_blk_parms[j].num_nodes_per_elem == 3)  /* 3-node TRI */
        list_len += 2;  /* 2 node side */
      else  /* 6-node TRI */
        list_len += 3;  /* 3 node side */
    }
    else if (elem_blk_parms[j].elem_type_val == EX_EL_UNK)
    {
      exerrval = EX_BADPARAM;
      sprintf(errmsg,
             "Error: %s in elem block %"PRId64" is an unsupported element type",
              elem_blk_parms[i].elem_type, elem_blk_parms[i].elem_blk_id);
      safe_free(elem_blk_parms);
      safe_free(elem_blk_ids);
      safe_free(ss_elem_ndx);
      safe_free(ss_elem_ndx_64);
      safe_free(side_set_side_list);
      safe_free(side_set_elem_list);
      ex_err("ex_get_side_set_node_list_len",errmsg,EX_MSG);
      return (EX_FATAL);
    }
    else /* all other element types */
      list_len += elem_blk_parms[j].num_nodes_per_side[0];
  }

  if (ex_int64_status(exoid) & EX_BULK_INT64_API)
    *(int64_t*)side_set_node_list_len = list_len;
  else
    *(int*)side_set_node_list_len = list_len;

  /* All done: release element block ids array,
     element block parameters array, and side set element index array */
  safe_free(elem_blk_ids);
  safe_free(elem_blk_parms);
  safe_free(ss_elem_ndx);
  safe_free(ss_elem_ndx_64);
  safe_free(side_set_side_list);
  safe_free(side_set_elem_list);

  return(EX_NOERR);
}
Пример #19
0
int ex_get_side_set_node_count(int exoid,
                               int side_set_id,
                               int *side_set_node_cnt_list)
{
  int ii, i, j, m; 
  int  num_side_sets, num_elem_blks, num_df, ndim;
  int tot_num_elem = 0, tot_num_ss_elem = 0, side, elem;
  int *elem_blk_ids;
  int *ss_elem_ndx;
  int *side_set_elem_list, *side_set_side_list;
  int elem_ctr;
  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_sides;
    int num_nodes_per_side[6];
    int num_attr;
    int elem_ctr;
    int elem_type_val;
  } *elem_blk_parms;

  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_count",errmsg,exerrval);
    return(EX_FATAL);
  }

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

  /* Lookup index of side set id in VAR_SS_IDS array */
  ex_id_lkup(exoid,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_count",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_count",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_count",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_count",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_count",errmsg,exerrval);
    return(EX_FATAL);
  }

  /* Allocate space for the side set element list */
  if (!(side_set_elem_list=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_count",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* Allocate space for the side set side list */
  if (!(side_set_side_list=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_count",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_count",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* Allocate space for the ss element index array */
  if (!(ss_elem_ndx=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_count",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=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_count",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_count",errmsg,EX_MSG);
    return(EX_FATAL);
  } 

  /* Allocate space for the element block params */
  if (!(elem_blk_parms=malloc(num_elem_blks*sizeof(struct elem_blk_parm))))
  {
    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_count",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_count",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; (size_t)m < 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;
      elem_blk_parms[i].num_sides = 1;
      elem_blk_parms[i].num_nodes_per_side[0] = 1;
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"SPHERE",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = SPHERE;
      elem_blk_parms[i].num_sides = 1;
        elem_blk_parms[i].num_nodes_per_side[0] = 1;
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"QUAD",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = QUAD;
      elem_blk_parms[i].num_sides = 4;
      if (elem_blk_parms[i].num_nodes_per_elem == 4) {
        elem_blk_parms[i].num_nodes_per_side[0] = 2;
        elem_blk_parms[i].num_nodes_per_side[1] = 2;
        elem_blk_parms[i].num_nodes_per_side[2] = 2;
        elem_blk_parms[i].num_nodes_per_side[3] = 2;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 5) {
        elem_blk_parms[i].num_nodes_per_side[0] = 2;
        elem_blk_parms[i].num_nodes_per_side[1] = 2;
        elem_blk_parms[i].num_nodes_per_side[2] = 2;
        elem_blk_parms[i].num_nodes_per_side[3] = 2;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 9 ||
                 elem_blk_parms[i].num_nodes_per_elem == 8) {
        elem_blk_parms[i].num_nodes_per_side[0] = 3;
        elem_blk_parms[i].num_nodes_per_side[1] = 3;
        elem_blk_parms[i].num_nodes_per_side[2] = 3;
        elem_blk_parms[i].num_nodes_per_side[3] = 3;
      } else {
        EL_NODE_COUNT_ERROR;
      }
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"TRIANGLE",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = TRIANGLE;
      if (ndim == 2) { /* 2d TRIs */
        elem_blk_parms[i].num_sides = 3;
        if (elem_blk_parms[i].num_nodes_per_elem == 3) {
          elem_blk_parms[i].num_nodes_per_side[0] = 2;
          elem_blk_parms[i].num_nodes_per_side[1] = 2;
          elem_blk_parms[i].num_nodes_per_side[2] = 2;
        } else if (elem_blk_parms[i].num_nodes_per_elem == 6) {
          elem_blk_parms[i].num_nodes_per_side[0] = 3;
          elem_blk_parms[i].num_nodes_per_side[1] = 3;
          elem_blk_parms[i].num_nodes_per_side[2] = 3;
        }
      } else if (ndim == 3) { /* 3d TRIs -- triangular shell*/
        elem_blk_parms[i].num_sides = 5; /* 2 Faces and 3 Edges */
        if (elem_blk_parms[i].num_nodes_per_elem == 3) {
          elem_blk_parms[i].num_nodes_per_side[0] = 3;
          elem_blk_parms[i].num_nodes_per_side[1] = 3;
          elem_blk_parms[i].num_nodes_per_side[2] = 2;
          elem_blk_parms[i].num_nodes_per_side[3] = 2;
          elem_blk_parms[i].num_nodes_per_side[4] = 2;
        } else if (elem_blk_parms[i].num_nodes_per_elem == 6) {
          elem_blk_parms[i].num_nodes_per_side[0] = 6;
          elem_blk_parms[i].num_nodes_per_side[1] = 6;
          elem_blk_parms[i].num_nodes_per_side[2] = 3;
          elem_blk_parms[i].num_nodes_per_side[3] = 3;
          elem_blk_parms[i].num_nodes_per_side[4] = 3;
        } else {
          EL_NODE_COUNT_ERROR;
        }
      }
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"SHELL",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = SHELL;

      if (elem_blk_parms[i].num_nodes_per_elem == 2) {/* KLUDGE for 2D Shells*/
        elem_blk_parms[i].num_sides = 2; 
        elem_blk_parms[i].num_nodes_per_side[0] = 2;
        elem_blk_parms[i].num_nodes_per_side[1] = 2;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 4) {
        elem_blk_parms[i].num_sides = 6;  /* 2 Faces, 4 Edges */
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
        elem_blk_parms[i].num_nodes_per_side[1] = 4;
        elem_blk_parms[i].num_nodes_per_side[2] = 2;
        elem_blk_parms[i].num_nodes_per_side[3] = 2;
        elem_blk_parms[i].num_nodes_per_side[4] = 2;
        elem_blk_parms[i].num_nodes_per_side[5] = 2;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 8 ||
                 elem_blk_parms[i].num_nodes_per_elem == 9) {
        elem_blk_parms[i].num_sides = 6;  /* 2 Faces, 4 Edges */
        elem_blk_parms[i].num_nodes_per_side[0] =
          elem_blk_parms[i].num_nodes_per_elem; /* 8 or 9 */
        elem_blk_parms[i].num_nodes_per_side[1] =
          elem_blk_parms[i].num_nodes_per_elem; /* 8 or 9 */
        elem_blk_parms[i].num_nodes_per_side[2] = 3;
        elem_blk_parms[i].num_nodes_per_side[3] = 3;
        elem_blk_parms[i].num_nodes_per_side[4] = 3;
        elem_blk_parms[i].num_nodes_per_side[5] = 3;
      } else {
        EL_NODE_COUNT_ERROR;
      }
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"HEX",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = HEX;
      elem_blk_parms[i].num_sides = 6;  
      /* determine side set node stride */
      if (elem_blk_parms[i].num_nodes_per_elem == 8) {  /* 8-node bricks */
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
        elem_blk_parms[i].num_nodes_per_side[1] = 4;
        elem_blk_parms[i].num_nodes_per_side[2] = 4;
        elem_blk_parms[i].num_nodes_per_side[3] = 4;
        elem_blk_parms[i].num_nodes_per_side[4] = 4;
        elem_blk_parms[i].num_nodes_per_side[5] = 4;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 9) { /* 9-node bricks */
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
        elem_blk_parms[i].num_nodes_per_side[1] = 4;
        elem_blk_parms[i].num_nodes_per_side[2] = 4;
        elem_blk_parms[i].num_nodes_per_side[3] = 4;
        elem_blk_parms[i].num_nodes_per_side[4] = 4;
        elem_blk_parms[i].num_nodes_per_side[5] = 4;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 12) { /* HEXSHELLS */
        elem_blk_parms[i].num_nodes_per_side[0] = 6;
        elem_blk_parms[i].num_nodes_per_side[1] = 6;
        elem_blk_parms[i].num_nodes_per_side[2] = 6;
        elem_blk_parms[i].num_nodes_per_side[3] = 6;
        elem_blk_parms[i].num_nodes_per_side[4] = 4;
        elem_blk_parms[i].num_nodes_per_side[5] = 4;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 20) { /* 20-node bricks */
        elem_blk_parms[i].num_nodes_per_side[0] = 8;
        elem_blk_parms[i].num_nodes_per_side[1] = 8;
        elem_blk_parms[i].num_nodes_per_side[2] = 8;
        elem_blk_parms[i].num_nodes_per_side[3] = 8;
        elem_blk_parms[i].num_nodes_per_side[4] = 8;
        elem_blk_parms[i].num_nodes_per_side[5] = 8;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 27) { /* 27-node bricks */
        elem_blk_parms[i].num_nodes_per_side[0] = 9;
        elem_blk_parms[i].num_nodes_per_side[1] = 9;
        elem_blk_parms[i].num_nodes_per_side[2] = 9;
        elem_blk_parms[i].num_nodes_per_side[3] = 9;
        elem_blk_parms[i].num_nodes_per_side[4] = 9;
        elem_blk_parms[i].num_nodes_per_side[5] = 9;
      } else {
        EL_NODE_COUNT_ERROR;
      }
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"TETRA",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = TETRA;
      elem_blk_parms[i].num_sides = 4;  
      /* determine side set node stride */
      if (elem_blk_parms[i].num_nodes_per_elem == 4) {
        elem_blk_parms[i].num_nodes_per_side[0] = 3;
        elem_blk_parms[i].num_nodes_per_side[1] = 3;
        elem_blk_parms[i].num_nodes_per_side[2] = 3;
        elem_blk_parms[i].num_nodes_per_side[3] = 3;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 8) {
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
        elem_blk_parms[i].num_nodes_per_side[1] = 4;
        elem_blk_parms[i].num_nodes_per_side[2] = 4;
        elem_blk_parms[i].num_nodes_per_side[3] = 4;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 10) {
        elem_blk_parms[i].num_nodes_per_side[0] = 6;
        elem_blk_parms[i].num_nodes_per_side[1] = 6;
        elem_blk_parms[i].num_nodes_per_side[2] = 6;
        elem_blk_parms[i].num_nodes_per_side[3] = 6;
      } else {
        EL_NODE_COUNT_ERROR;
      }
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"WEDGE",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = WEDGE;
      elem_blk_parms[i].num_sides = 5;  
      if (elem_blk_parms[i].num_nodes_per_elem == 6) {
        elem_blk_parms[i].num_nodes_per_side[0] = 4;
        elem_blk_parms[i].num_nodes_per_side[1] = 4;
        elem_blk_parms[i].num_nodes_per_side[2] = 4;
        elem_blk_parms[i].num_nodes_per_side[3] = 3;
        elem_blk_parms[i].num_nodes_per_side[4] = 3;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 15){
        elem_blk_parms[i].num_nodes_per_side[0] = 8;
        elem_blk_parms[i].num_nodes_per_side[1] = 8;
        elem_blk_parms[i].num_nodes_per_side[2] = 8;
        elem_blk_parms[i].num_nodes_per_side[3] = 6;
        elem_blk_parms[i].num_nodes_per_side[4] = 6;
      } else {
        EL_NODE_COUNT_ERROR;
      }
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"PYRAMID",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = PYRAMID;
      elem_blk_parms[i].num_sides = 5;  
      if (elem_blk_parms[i].num_nodes_per_elem == 5) {
        elem_blk_parms[i].num_nodes_per_side[0] = 3;
        elem_blk_parms[i].num_nodes_per_side[1] = 3;
        elem_blk_parms[i].num_nodes_per_side[2] = 3;
        elem_blk_parms[i].num_nodes_per_side[3] = 3;
        elem_blk_parms[i].num_nodes_per_side[4] = 4;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 13){
        elem_blk_parms[i].num_nodes_per_side[0] = 6;
        elem_blk_parms[i].num_nodes_per_side[1] = 6;
        elem_blk_parms[i].num_nodes_per_side[2] = 6;
        elem_blk_parms[i].num_nodes_per_side[3] = 6;
        elem_blk_parms[i].num_nodes_per_side[4] = 8;
      } else {
        EL_NODE_COUNT_ERROR;
      }
    }
    else if (strncmp(elem_blk_parms[i].elem_type,"BEAM",3) == 0)
    {
      elem_blk_parms[i].elem_type_val = BEAM;
      elem_blk_parms[i].num_sides = 2;  

      if (elem_blk_parms[i].num_nodes_per_elem == 2) {
        elem_blk_parms[i].num_nodes_per_side[0] = 2;
        elem_blk_parms[i].num_nodes_per_side[1] = 2;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 3){
        elem_blk_parms[i].num_nodes_per_side[0] = 3;
        elem_blk_parms[i].num_nodes_per_side[1] = 3;
      } else {
        EL_NODE_COUNT_ERROR;
      }
    }
    else if ( (strncmp(elem_blk_parms[i].elem_type,"TRUSS",3) == 0) ||
              (strncmp(elem_blk_parms[i].elem_type,"BAR",3) == 0) ||
              (strncmp(elem_blk_parms[i].elem_type,"EDGE",3) == 0) )
    {
      elem_blk_parms[i].elem_type_val = TRUSS;
      elem_blk_parms[i].num_sides = 2;  

      if (elem_blk_parms[i].num_nodes_per_elem == 2) {
        elem_blk_parms[i].num_nodes_per_side[0] = 2;
        elem_blk_parms[i].num_nodes_per_side[1] = 2;
      } else if (elem_blk_parms[i].num_nodes_per_elem == 3) {
        elem_blk_parms[i].num_nodes_per_side[0] = 3;
        elem_blk_parms[i].num_nodes_per_side[1] = 3;
      } else {
        EL_NODE_COUNT_ERROR;
      }
    }
    /* Used for an empty block in a parallel decomposition */
    else if (strncmp(elem_blk_parms[i].elem_type,"NULL",3) == 0) {
      elem_blk_parms[i].elem_type_val = '\0';
      elem_blk_parms[i].num_sides = 0;  
      elem_blk_parms[i].num_nodes_per_side[0] = 0;
      elem_blk_parms[i].num_elem_in_blk = 0;
    } else {
      /* unsupported element type; no problem if no sides specified for
         this element block */
      elem_blk_parms[i].elem_type_val = UNK;
      elem_blk_parms[i].num_sides = 0;  
      elem_blk_parms[i].num_nodes_per_side[0] = 0;
    }

    elem_blk_parms[i].elem_blk_id = 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 */
  }


  /* Finally... Create the list of node counts for each face in the
   * side set.
   */

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

    i = ss_elem_ndx[ii];
    elem = side_set_elem_list[i];
    side = side_set_side_list[i]-1; /* Convert to 0-based sides */

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

    if (j < num_elem_blks) {
      assert(side < elem_blk_parms[j].num_sides);  
      side_set_node_cnt_list[i] = elem_blk_parms[j].num_nodes_per_side[side];
    } else {
      exerrval = EX_BADPARAM;
      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(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_count",errmsg,EX_MSG);
      return (EX_FATAL);
    }
  }

  /* All done: release connectivity array space, element block ids
   * array, element block parameters array, and side set element index
   * array
   */
  free(elem_blk_ids);
  free(elem_blk_parms);
  free(ss_elem_ndx);
  free(side_set_side_list);
  free(side_set_elem_list);

  return(EX_NOERR);
}
//----------------------------------------------------------------------------
void vtkExodusReader::ExecuteInformation()
{
  int exoid;
  int error;
  int CPU_word_size, IO_word_size;
  float version;
  float fdum;
  int num_node_sets, num_side_sets;
  int num_node_vars, num_ele_vars;
  //char *coord_names[3];
  int i;
  int num_elem_in_block;
  int num_nodes_per_elem;
  int num_attr;
  int *ids;
  char *cdum = NULL;
  char elem_type[MAX_STR_LENGTH+1];
  
  CPU_word_size = 0;  // float or double.
  IO_word_size = 0;
  
  exoid = ex_open(this->FileName, EX_READ, &CPU_word_size, &IO_word_size,
                  &version);
  if (exoid < 0)
    {
    vtkErrorMacro("Problem reading information from file " << this->FileName);
    return;
    }
  
  if (this->Title == NULL)
    {
    this->Title = new char[MAX_LINE_LENGTH+1];
    }
  error = ex_get_init(exoid, this->Title, &this->Dimensionality, 
                      &this->NumberOfNodes, &this->NumberOfElements, 
                      &this->NumberOfBlocks, &num_node_sets, &num_side_sets);

  if (error < 0)
    {
    vtkErrorMacro("Error: " << error << " initializing exodus file " << this->FileName);
    }
  
  // Read coordinate names. What will we do with these?
  //for (i = 0; i < num_dim; ++i)
  //  {
  //  coord_names[i] = new char [MAX_STR_LENGTH+1];
  //  }
  //error = ex_get_coord_names(exoid, coord_names);
  //for (i = 0; i < num_dim; ++i)
  //  {
  //  delete [] coord_names[i];
  //  coord_names[i] = NULL;
  //  }
  
  // Read element block paramemters.
  this->NumberOfBlockElements->Reset();
  this->BlockIds->Reset();
  this->BlockIds->SetNumberOfValues(this->NumberOfBlocks);
  ids = this->BlockIds->GetPointer((int)(0));
  error = ex_get_elem_blk_ids (exoid, ids);
  for (i = 0; i < this->NumberOfBlocks; ++i)
    {
    error = ex_get_elem_block (exoid, ids[i], elem_type,
                               &(num_elem_in_block),
                               &(num_nodes_per_elem), &(num_attr));
    if (error < 0)
      {
      vtkErrorMacro("Error: " << error << " reading block information from file " 
                    << this->FileName);
      }
    
    this->NumberOfBlockElements->InsertValue(i, num_elem_in_block);
    }

  // Read the attribute array information.
  error = ex_get_var_param(exoid, "n", &(num_node_vars));
  if (error < 0)
    {
    vtkErrorMacro("Error: " << error << " while reading number of point array from file " 
                  << this->FileName);
    }
  this->SetNumberOfPointDataArrays(num_node_vars);
  if (num_node_vars > 0)
    {
    error = ex_get_var_names(exoid, "n", num_node_vars,
                             this->PointDataArrayNames);
    if (error < 0)
      {
      vtkErrorMacro("Error: " << error << " while reading point array names from file " 
                    << this->FileName);
      }
    this->NumberOfPointDataArrays = 
      this->SimplifyArrayNames(this->PointDataArrayNames, 
                               this->PointDataArrayNumberOfComponents,
                               this->NumberOfPointDataArrays);
    }
  
  
  // Cell array names
  error = ex_get_var_param(exoid, "e", &(num_ele_vars));
  if (error < 0)
    {
    vtkErrorMacro("Error: " << error 
                  << " while reading number of element array from file " 
                  << this->FileName);
    }
  this->SetNumberOfCellDataArrays(num_ele_vars);
  if (num_ele_vars > 0)
    {
    // not all cell variables exist over all element blocks.  A "truth table"
    // will say whether a variable is defined for a certain block.
    this->CellVarTruthTable->Resize(num_ele_vars*this->NumberOfBlocks);
    int *ptr = CellVarTruthTable->GetPointer(0);
    ex_get_elem_var_tab(exoid, this->NumberOfBlocks, num_ele_vars, ptr);

    error = ex_get_var_names (exoid, "e", num_ele_vars, this->CellDataArrayNames);
    if (error < 0)
      {
      vtkErrorMacro("Error: " << error 
                    << " while reading element array names from file " 
                    << this->FileName);
      }

    this->NumberOfCellDataArrays = 
      this->SimplifyArrayNames(this->CellDataArrayNames, 
                               this->CellDataArrayNumberOfComponents,
                               this->NumberOfCellDataArrays);
    }
  
  // Read the number of time steps available.
  error = ex_inquire(exoid, EX_INQ_TIME, &this->NumberOfTimeSteps, &fdum,cdum);
  if (error < 0)
    {
    vtkErrorMacro("Error: " << error << " while reading number of time steps from file " 
                  << this->FileName);
    }
  
  error = ex_close(exoid);
  if (error < 0)
    {
    vtkErrorMacro("Error: " << error << " closing file " 
                  << this->FileName);
    }
  
  if (this->StartBlock < 0)
    {
    this->StartBlock = 0;
    this->EndBlock = this->NumberOfBlocks - 1;
    }
}
Пример #21
0
int read_exoII_file(int Proc,
                    int Num_Proc,
                    PROB_INFO_PTR prob,
                    PARIO_INFO_PTR pio_info,
                    MESH_INFO_PTR mesh)
{
#ifndef ZOLTAN_NEMESIS
  Gen_Error(0, "Fatal:  Nemesis requested but not linked with driver.");
  return 0;

#else /* ZOLTAN_NEMESIS */
  /* Local declarations. */
  char  *yo = "read_exoII_mesh";
  char   par_nem_fname[FILENAME_MAX+1], title[MAX_LINE_LENGTH+1];
  char   cmesg[256];

  float  ver;

  int    i, pexoid, cpu_ws = 0, io_ws = 0;
  int   *nnodes = NULL, *etypes = NULL;
#ifdef DEBUG_EXO
  int    j, k, elem;
#endif
  FILE  *fdtmp;

/***************************** BEGIN EXECUTION ******************************/

  DEBUG_TRACE_START(Proc, yo);

  /* since this is a test driver, set error reporting in exodus */
  ex_opts(EX_VERBOSE | EX_DEBUG);

  /* generate the parallel filename for this processor */
  gen_par_filename(pio_info->pexo_fname, par_nem_fname, pio_info, Proc,
                   Num_Proc);

  /* 
   * check whether parallel file exists.  do the check with fopen 
   * as ex_open coredumps on the paragon when files do not exist.
   */

  if ((fdtmp = fopen(par_nem_fname, "r")) == NULL) {
    sprintf(cmesg,"fatal: parallel Exodus II file %s does not exist",
            par_nem_fname);
    Gen_Error(0, cmesg);
    return 0;
  }
  else
    fclose(fdtmp);

  /*
   * now open the existing parallel file using Exodus calls.
   */

  if ((pexoid = ex_open(par_nem_fname, EX_READ, &cpu_ws, &io_ws,
                        &ver)) < 0) {
    sprintf(cmesg,"fatal: could not open parallel Exodus II file %s",
            par_nem_fname);
    Gen_Error(0, cmesg);
    return 0;
  }

  /* and get initial information */
  if (ex_get_init(pexoid, title, &(mesh->num_dims),
                  &(mesh->num_nodes), &(mesh->num_elems),
                  &(mesh->num_el_blks), &(mesh->num_node_sets),
                  &(mesh->num_side_sets)) < 0) {
    Gen_Error(0, "fatal: Error returned from ex_get_init");
    return 0;
  }


  /* alocate some memory for the element blocks */
  mesh->data_type = MESH;
  mesh->vwgt_dim = 1;  /* One weight for now. */
  mesh->ewgt_dim = 1;  /* One weight for now. */
  mesh->eb_etypes = (int *) malloc (5 * mesh->num_el_blks * sizeof(int));
  if (!mesh->eb_etypes) {
    Gen_Error(0, "fatal: insufficient memory");
    return 0;
  }
  mesh->eb_ids = mesh->eb_etypes + mesh->num_el_blks;
  mesh->eb_cnts = mesh->eb_ids + mesh->num_el_blks;
  mesh->eb_nnodes = mesh->eb_cnts + mesh->num_el_blks;
  mesh->eb_nattrs = mesh->eb_nnodes + mesh->num_el_blks;

  mesh->eb_names = (char **) malloc (mesh->num_el_blks * sizeof(char *));
  if (!mesh->eb_names) {
    Gen_Error(0, "fatal: insufficient memory");
    return 0;
  }

  mesh->hindex = (int *) malloc(sizeof(int));
  mesh->hindex[0] = 0;

  if (ex_get_elem_blk_ids(pexoid, mesh->eb_ids) < 0) {
    Gen_Error(0, "fatal: Error returned from ex_get_elem_blk_ids");
    return 0;
  }

  /* allocate temporary storage for items needing global reduction.   */
  /* nemesis does not store most element block info about blocks for  */
  /* which the processor owns no elements.                            */
  /* we, however, use this information in migration, so we need to    */
  /* accumulate it for all element blocks.    kdd 2/2001              */

  if (mesh->num_el_blks > 0) {
    nnodes = (int *) malloc(2 * mesh->num_el_blks * sizeof(int));
    if (!nnodes) {
      Gen_Error(0, "fatal: insufficient memory");
      return 0;
    }
    etypes = nnodes + mesh->num_el_blks;
  }

  /* get the element block information */
  for (i = 0; i < mesh->num_el_blks; i++) {

    /* allocate space for name */
    mesh->eb_names[i] = (char *) malloc((MAX_STR_LENGTH+1) * sizeof(char));
    if (!mesh->eb_names[i]) {
      Gen_Error(0, "fatal: insufficient memory");
      return 0;
    }

    if (ex_get_elem_block(pexoid, mesh->eb_ids[i], mesh->eb_names[i],
                          &(mesh->eb_cnts[i]), &(nnodes[i]),
                          &(mesh->eb_nattrs[i])) < 0) {
      Gen_Error(0, "fatal: Error returned from ex_get_elem_block");
      return 0;
    }

    if (mesh->eb_cnts[i] > 0) {
      if ((etypes[i] =  (int) get_elem_type(mesh->eb_names[i],
                                            nnodes[i],
                                            mesh->num_dims)) == E_TYPE_ERROR) {
        Gen_Error(0, "fatal: could not get element type");
        return 0;
      }
    }
    else etypes[i] = (int) NULL_EL;
  }

  /* Perform reduction on necessary fields of element blocks.  kdd 2/2001 */
  MPI_Allreduce(nnodes, mesh->eb_nnodes, mesh->num_el_blks, MPI_INT, MPI_MAX, 
                MPI_COMM_WORLD);
  MPI_Allreduce(etypes, mesh->eb_etypes, mesh->num_el_blks, MPI_INT, MPI_MIN, 
                MPI_COMM_WORLD);
  for (i = 0; i < mesh->num_el_blks; i++) {
    strcpy(mesh->eb_names[i], get_elem_name(mesh->eb_etypes[i]));
  }
  free(nnodes);

  /*
   * allocate memory for the elements
   * allocate a little extra for element migration latter
   */
  mesh->elem_array_len = mesh->num_elems + 5;
  mesh->elements = (ELEM_INFO_PTR) malloc (mesh->elem_array_len 
                                         * sizeof(ELEM_INFO));
  if (!(mesh->elements)) {
    Gen_Error(0, "fatal: insufficient memory");
    return 0;
  }

  /*
   * intialize all of the element structs as unused by
   * setting the globalID to -1
   */
  for (i = 0; i < mesh->elem_array_len; i++) 
    initialize_element(&(mesh->elements[i]));

  /* read the information for the individual elements */
  if (!read_elem_info(pexoid, Proc, prob, mesh)) {
    Gen_Error(0, "fatal: Error returned from read_elem_info");
    return 0;
  }

  /* read the communication information */
  if (!read_comm_map_info(pexoid, Proc, prob, mesh)) {
    Gen_Error(0, "fatal: Error returned from read_comm_map_info");
    return 0;
  }

  /* Close the parallel file */
  if(ex_close (pexoid) < 0) {
    Gen_Error(0, "fatal: Error returned from ex_close");
    return 0;
  }

  /* print out the distributed mesh */
  if (Debug_Driver > 3)
    print_distributed_mesh(Proc, Num_Proc, mesh);

  DEBUG_TRACE_END(Proc, yo);
  return 1;

#endif /* ZOLTAN_NEMESIS */
}
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);
}
Пример #23
0
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);
}
Пример #24
0
char *do_exodus_meta(char *filename)
{
  int exoid;
  int ndim, nnodes, nelems, nblks, nnsets, nssets;
  char *title;
  symrec *ptr;

  int *ids = NULL;
  
  /*
   * Open the specified exodusII file, read the metadata and set
   * variables for each item.
   * Examples include "node_count", "element_count", ...
   */
  exoid = open_exodus_file(filename);
  if (exoid < 0) return "";

  /* read database paramters */
  title = (char *)calloc ((MAX_LINE_LENGTH+1),sizeof(char *));
  ex_get_init(exoid,title,&ndim,&nnodes,&nelems,&nblks,&nnsets,&nssets);
  
  ptr = putsym("ex_title", SVAR, 0);
  ptr->value.svar = title;

  ptr = putsym("ex_dimension", VAR, 0);
  ptr->value.var = ndim;

  ptr = putsym("ex_node_count", VAR, 0);
  ptr->value.var = nnodes;

  ptr = putsym("ex_element_count", VAR, 0);
  ptr->value.var = nelems;

  ptr = putsym("ex_block_count", VAR, 0);
  ptr->value.var = nblks;

  ptr = putsym("ex_nset_count", VAR, 0);
  ptr->value.var = nnsets;

  ptr = putsym("ex_sset_count", VAR, 0);
  ptr->value.var = nssets;
  
  { /* Nemesis Information */
    int proc_count;
    int proc_in_file;
    char file_type[MAX_STR_LENGTH+1];

    int global_nodes;
    int global_elements;
    int global_blocks;
    int global_nsets;
    int global_ssets;
    int error;
    
    error = ex_get_init_info(exoid, &proc_count, &proc_in_file, file_type);

    if (error >= 0) {
      ptr = putsym("ex_processor_count", VAR, 0);
      ptr->value.var = proc_count;
      
      ex_get_init_global(exoid, &global_nodes, &global_elements,
			 &global_blocks, &global_nsets, &global_ssets);
      
      ptr = putsym("ex_node_count_global", VAR, 0);
      ptr->value.var = global_nodes;
      
      ptr = putsym("ex_element_count_global", VAR, 0);
      ptr->value.var = global_elements;
    }
  }
    
  /*
   * Read The Element Blocks And Set Variables For Those Also.
   * The Scheme Is:
   * -- 'Ex_Block_Ids' Is A List Of Ids.  Due To Aprepro Limitations,
   *     This List Is A String, Not An Integer List...
   * -- Each Block Is Named 'Ex_Block_X' Where X Is Replaced By The
   *    Blocks Position In The List. For Example, The First Block Will
   *    Be Named 'Ex_Block_1'
   *
   * -- Each Block Will Have The Following Symbols:
   *    -- Ex_Block_X_Id = Id Of This Element Block
   *    -- Ex_Block_X_Name = Composed Name "Block_" + Id
   *    -- Ex_Block_X_Element_Count = Number Of Elements In Block
   *    -- Ex_Block_X_Nodes_Per_Element = Number Of Nodes Per Element
   *    -- Ex_Block_X_Topology = Type Of Elements In Block
   *      (Lowercased)
   *    -- Ex_Block_X_Attribute_Count = Number Of Attributes.
   */

  ids = malloc(nblks * sizeof(int));
  ex_get_elem_blk_ids (exoid, ids);

  {
    int i;
    char *buffer = NULL;
    char cid[33];     /* arbitrary size, large enough for INT_MAX */
    int size = 2048;
    char *tmp = NULL;
    
    buffer = calloc(size, sizeof(char));
    if (buffer != NULL) {
      for (i=0; i < nblks; i++) {
	sprintf(cid, "%d ", ids[i]);
	if (strlen(buffer) + strlen(cid) +1 > size) {
	  if (realloc(buffer, size *=2) == NULL) {
	    free(buffer);
	    yyerror("Error allocating memory.");
	  }
	  memset(&buffer[size/2], 0, size/2);
	}
	strcat(buffer, cid);
      }
      NEWSTR(buffer, tmp);
      ptr = putsym("ex_block_ids", SVAR, 0);
      ptr->value.svar = tmp;
      free(buffer);
    }
  }
    
  {
    int i;
    char var[128];
    char type[MAX_STR_LENGTH+1];
    char *tmp = NULL;
    int nel;
    int nnel;
    int natr;
    
    for (i=0; i < nblks; i++) {
      ex_get_elem_block(exoid, ids[i], type, &nel, &nnel, &natr);

      sprintf(var, "ex_block_seq_%d_id", i+1);
      ptr = putsym(var, VAR, 0);
      ptr->value.var = ids[i];

      sprintf(var, "ex_block_%d_name", ids[i]);
      ptr = putsym(var, SVAR, 0);
      sprintf(var, "block_%d", ids[i]);
      NEWSTR(var, tmp);
      ptr->value.svar = tmp;

      sprintf(var, "ex_block_%d_element_count", ids[i]);
      ptr = putsym(var, VAR, 0);
      ptr->value.var = nel;

      sprintf(var, "ex_block_%d_nodes_per_element", ids[i]);
      ptr = putsym(var, VAR, 0);
      ptr->value.var = nnel;

      sprintf(var, "ex_block_%d_topology", ids[i]);
      ptr = putsym(var, SVAR, 0);
      NEWSTR(type, tmp);

      /* lowercase the string */
      LowerCaseTrim(tmp);
      ptr->value.svar = tmp;

      sprintf(var, "ex_block_%d_attribute_count", ids[i]);
      ptr = putsym(var, VAR, 0);
      ptr->value.var = natr;
    }
  }
  if (ids != NULL) free(ids);

  {
    /* Get timestep count */
    int ts_count = ex_inquire_int(exoid, EX_INQ_TIME);
    ptr = putsym("ex_timestep_count", VAR, 0);
    ptr->value.var = ts_count;
    
    if (ts_count > 0) {
      int i;
      symrec *format = getsym("_FORMAT");
      char *buffer = NULL;
      char cid[33];     /* arbitrary size, large enough for double... */
      int size = 2048;
      char *tmp = NULL;
      double *timesteps = malloc(ts_count * sizeof(double));

      ex_get_all_times(exoid, timesteps);

      buffer = calloc(size, sizeof(char));
      if (buffer != NULL) {

	for (i=0; i < ts_count; i++) {
	  sprintf(cid, format->value.svar, timesteps[i]);
	  if (strlen(buffer) + strlen(cid) +2 > size) {
	    if (realloc(buffer, size *=2) == NULL) {
	      free(buffer);
	      yyerror("Error allocating memory.");
	    }
	    memset(&buffer[size/2], 0, size/2);
	  }
	  strcat(buffer, cid);
	  strcat(buffer, " ");
	}
	NEWSTR(buffer, tmp);
	ptr = putsym("ex_timestep_times", SVAR, 0);
	ptr->value.svar = tmp;

	free(buffer);
      }
    }
  }
  
  ex_close(exoid);
  return "";
}