Esempio n. 1
0
static exodus_file_t* open_exodus_file(MPI_Comm comm,
                                       const char* filename,
                                       int mode)
{
  set_ex_opts();

  exodus_file_t* file = polymec_malloc(sizeof(exodus_file_t));
  file->last_time_index = 0;
  file->comm = comm;
  int real_size = (int)sizeof(real_t);
  file->ex_real_size = 0;
#if POLYMEC_HAVE_MPI
  MPI_Info_create(&file->mpi_info);
  if (mode & EX_READ)
  {
    file->ex_id = ex_open_par(filename, mode, &real_size,
                              &file->ex_real_size, &file->ex_version, 
                              file->comm, file->mpi_info);

    // Did that work? If not, try the serial opener.
    if (file->ex_id < 0)
    {
      file->ex_id = ex_open(filename, mode, &real_size,
                            &file->ex_real_size, &file->ex_version);
    }
  }
  else
  {
    ASSERT(mode & EX_CLOBBER);
    file->ex_version = EX_API_VERS;
    file->ex_id = ex_create_par(filename, mode, &real_size,
                                &file->ex_real_size, 
                                file->comm, file->mpi_info);

    // Did that work? If not, try the serial creator.
    if (file->ex_id < 0)
    {
      exerrval = 0;
      file->ex_id = ex_create(filename, mode, &real_size,
                              &file->ex_real_size);
    }
  }
#else
  if (mode & EX_READ)
  {
    file->ex_id = ex_open(filename, mode, &real_size,
                          &file->ex_real_size, &file->ex_version);
  }
  else
  {
    ASSERT(mode & EX_CLOBBER);
    file->ex_id = ex_create(filename, mode, &real_size, &file->ex_real_size);
    file->ex_version = EX_API_VERS;
  }
#endif
  if (file->ex_id >= 0)
  {
    file->writing = (mode & EX_CLOBBER);
    file->node_var_names = string_array_new();
    file->node_set_var_names = string_array_new();
    file->edge_var_names = string_array_new();
    file->edge_set_var_names = string_array_new();
    file->face_var_names = string_array_new();
    file->face_set_var_names = string_array_new();
    file->elem_var_names = string_array_new();
    file->elem_set_var_names = string_array_new();
    file->side_set_var_names = string_array_new();

    if (!file->writing)
    {
      // Read all the available variable names.
      fetch_all_variable_names(file);

      // Get information from the file.
      ex_init_params mesh_info;
      int status = ex_get_init_ext(file->ex_id, &mesh_info);
      if ((status >= 0) && (mesh_info.num_dim == 3))
      {
        strncpy(file->title, mesh_info.title, MAX_NAME_LENGTH);
        file->num_nodes = (int)mesh_info.num_nodes;
        file->num_elem = (int)mesh_info.num_elem;
        file->num_faces = (int)mesh_info.num_face;
        file->num_edges = (int)mesh_info.num_edge;
        file->num_elem_blocks = (int)mesh_info.num_elem_blk;
        file->elem_block_ids = polymec_malloc(sizeof(int) * file->num_elem_blocks);
        if (file->num_elem_blocks > 0)
          ex_get_ids(file->ex_id, EX_ELEM_BLOCK, file->elem_block_ids);
        file->num_face_blocks = (int)mesh_info.num_face_blk;
        file->face_block_ids = polymec_malloc(sizeof(int) * file->num_face_blocks);
        if (file->num_face_blocks > 0)
          ex_get_ids(file->ex_id, EX_FACE_BLOCK, file->face_block_ids);
        file->num_edge_blocks = (int)mesh_info.num_edge_blk;
        file->edge_block_ids = polymec_malloc(sizeof(int) * file->num_edge_blocks);
        if (file->num_edge_blocks > 0)
          ex_get_ids(file->ex_id, EX_EDGE_BLOCK, file->edge_block_ids);
        file->num_elem_sets = (int)mesh_info.num_elem_sets;
        file->num_face_sets = (int)mesh_info.num_face_sets;
        file->num_edge_sets = (int)mesh_info.num_edge_sets;
        file->num_node_sets = (int)mesh_info.num_node_sets;
        file->num_side_sets = (int)mesh_info.num_side_sets;
      }
    }
    else
    {
      // By default, the title of the database is its filename.
      strncpy(file->title, filename, MAX_NAME_LENGTH);
      file->num_nodes = 0;
      file->num_edges = 0;
      file->num_faces = 0;
      file->num_elem = 0;
      file->num_elem_blocks = 0;
      file->elem_block_ids = NULL;
      file->num_face_blocks = 0;
      file->face_block_ids = NULL;
      file->num_edge_blocks = 0;
      file->edge_block_ids = NULL;
      file->num_elem_sets = 0;
      file->num_face_sets = 0;
      file->num_edge_sets = 0;
      file->num_node_sets = 0;
      file->num_side_sets = 0;
    }
  }
  else
  {
    polymec_free(file);
    file = NULL;
  }

  return file;
}
Esempio n. 2
0
int cReadEdgeFace(int argc, char *argv[])
{
  int            exoid;
  int            appWordSize  = 8;
  int            diskWordSize = 8;
  float          exoVersion;
  int            itmp[5];
  int *          ids;
  int            nids;
  int            obj;
  int            i, j;
  int            num_timesteps;
  int            ti;
  char **        obj_names;
  char **        var_names;
  int            have_var_names;
  int            num_vars;    /* number of variables per object */
  int            num_entries; /* number of values per variable per object */
  double *       entry_vals;  /* variable values for each entry of an object */
  ex_init_params modelParams;

  exoid = ex_open(EX_TEST_FILENAME, EX_READ, &appWordSize, &diskWordSize, &exoVersion);
  if (exoid <= 0) {
    fprintf(stderr, "Unable to open \"%s\" for reading.\n", EX_TEST_FILENAME);
    return 1;
  }

  EXCHECK(ex_get_init_ext(exoid, &modelParams), "Unable to read database parameters.\n");

  fprintf(stdout, "Title: <%s>\n"
                  "Dimension: %" PRId64 "\n"
                  "Nodes: %" PRId64 "\n"
                  "Edges: %" PRId64 "\n"
                  "Faces: %" PRId64 "\n"
                  "Elements: %" PRId64 "\n"
                  "Edge Blocks: %" PRId64 "\n"
                  "Face Blocks: %" PRId64 "\n"
                  "Element Blocks: %" PRId64 "\n"
                  "Node Sets: %" PRId64 "\n"
                  "Edge Sets: %" PRId64 "\n"
                  "Face Sets: %" PRId64 "\n"
                  "Side Sets: %" PRId64 "\n"
                  "Element Sets: %" PRId64 "\n"
                  "Node Maps: %" PRId64 "\n"
                  "Edge Maps: %" PRId64 "\n"
                  "Face Maps: %" PRId64 "\n"
                  "Element Maps: %" PRId64 "\n",
          modelParams.title, modelParams.num_dim, modelParams.num_nodes, modelParams.num_edge,
          modelParams.num_face, modelParams.num_elem, modelParams.num_edge_blk,
          modelParams.num_face_blk, modelParams.num_elem_blk, modelParams.num_node_sets,
          modelParams.num_edge_sets, modelParams.num_face_sets, modelParams.num_side_sets,
          modelParams.num_elem_sets, modelParams.num_node_maps, modelParams.num_edge_maps,
          modelParams.num_face_maps, modelParams.num_elem_maps);

  num_timesteps = ex_inquire_int(exoid, EX_INQ_TIME);

  /* *** NEW API *** */
  for (i = 0; i < sizeof(obj_types) / sizeof(obj_types[0]); ++i) {
    int *truth_tab = 0;
    have_var_names = 0;

    EXCHECK(ex_inquire(exoid, obj_sizes[i], &nids, 0, 0),
            "Object ID list size could not be determined.\n");

    if (!nids) {
      fprintf(stdout, "=== %ss: none\n\n", obj_typenames[i]);
      continue;
    }
    else {
      fprintf(stdout, "=== %ss: %d\n", obj_typenames[i], nids);
    }

    ids       = (int *)malloc(nids * sizeof(int));
    obj_names = (char **)malloc(nids * sizeof(char *));
    for (obj         = 0; obj < nids; ++obj)
      obj_names[obj] = (char *)malloc((MAX_STR_LENGTH + 1) * sizeof(char));

    EXCHECK(ex_get_ids(exoid, obj_types[i], ids), "Could not read object ids.\n");
    EXCHECK(ex_get_names(exoid, obj_types[i], obj_names), "Could not read object ids.\n");

    if ((OBJECT_IS_BLOCK(i)) || (OBJECT_IS_SET(i))) {
      int *tp;
      EXCHECK(ex_get_variable_param(exoid, obj_types[i], &num_vars),
              "Could not read number of variables.\n");

      if (num_vars && num_timesteps > 0) {
        truth_tab = (int *)malloc(num_vars * nids * sizeof(int));
        EXCHECK(ex_get_truth_table(exoid, obj_types[i], nids, num_vars, truth_tab),
                "Could not read truth table.\n");
        tp = truth_tab;
        fprintf(stdout, "Truth:");
        for (obj = 0; obj < nids; ++obj) {
          for (j = 0; j < num_vars; ++j, ++tp) {
            fprintf(stdout, " %d", *tp);
          }
          fprintf(stdout, "\n      ");
        }
        fprintf(stdout, "\n");

        var_names = (char **)malloc(num_vars * sizeof(char *));
        for (j         = 0; j < num_vars; ++j)
          var_names[j] = (char *)malloc((MAX_STR_LENGTH + 1) * sizeof(char));

        EXCHECK(ex_get_variable_names(exoid, obj_types[i], num_vars, var_names),
                "Could not read variable names.\n");
        have_var_names = 1;
      }
    }

    if (!have_var_names)
      var_names = 0;

    for (obj = 0; obj < nids; ++obj) {
      if (obj_names[obj])
        fprintf(stdout, "%s %3d (%s): ", obj_typenames[i], ids[obj], obj_names[obj]);
      else
        fprintf(stdout, "%s %3d: ", obj_typenames[i], ids[obj]);

      if (OBJECT_IS_BLOCK(i)) {
        int *nconn;
        int *econn;
        int *fconn;
        int  ele;
        int  ctr;
        int  num_attrs;
        if (obj_types[i] == EX_ELEM_BLOCK) {
          EXCHECK(ex_get_block(exoid, obj_types[i], ids[obj], 0, itmp, itmp + 1, itmp + 2, itmp + 3,
                               &num_attrs),
                  "Could not read block params.\n");
          fprintf(stdout,
                  "Entries: %3d Nodes/entry: %d Edges/entry: %d Faces/entry: %d Attributes: %d",
                  itmp[0], itmp[1], itmp[2], itmp[3], num_attrs);
        }
        else {
          EXCHECK(ex_get_block(exoid, obj_types[i], ids[obj], 0, itmp, itmp + 1, 0, 0, &num_attrs),
                  "Could not read block params.\n");
          fprintf(stdout, "Entries: %3d Nodes/entry: %d Attributes: %d", itmp[0], itmp[1],
                  num_attrs);
          itmp[2] = itmp[3] = 0;
        }
        fprintf(stdout, "\n   ");
        num_entries = itmp[0];
        nconn       = itmp[1] ? (int *)malloc(itmp[1] * num_entries * sizeof(int)) : 0;
        econn       = itmp[2] ? (int *)malloc(itmp[2] * num_entries * sizeof(int)) : 0;
        fconn       = itmp[3] ? (int *)malloc(itmp[3] * num_entries * sizeof(int)) : 0;
        EXCHECK(ex_get_conn(exoid, obj_types[i], ids[obj], nconn, econn, fconn),
                "Could not read connectivity.\n");
        for (ele = 0; ele < num_entries; ++ele) {
          for (ctr = 0; ctr < itmp[1]; ++ctr) {
            fprintf(stdout, " %2d", nconn[ele * itmp[1] + ctr]);
          }
          if (itmp[2]) {
            fprintf(stdout, "  ++");
            for (ctr = 0; ctr < itmp[2]; ++ctr) {
              fprintf(stdout, " %2d", econn[ele * itmp[2] + ctr]);
            }
          }
          if (itmp[3]) {
            fprintf(stdout, "  ++");
            for (ctr = 0; ctr < itmp[3]; ++ctr) {
              fprintf(stdout, " %2d", fconn[ele * itmp[3] + ctr]);
            }
          }
          fprintf(stdout, "\n   ");
        }
        free(nconn);
        free(econn);
        free(fconn);

        if (num_attrs) {
          char ** attr_names;
          double *attr;
          attr       = (double *)malloc(num_entries * num_attrs * sizeof(double));
          attr_names = (char **)malloc(num_attrs * sizeof(char *));
          for (j          = 0; j < num_attrs; ++j)
            attr_names[j] = (char *)malloc((MAX_STR_LENGTH + 1) * sizeof(char));

          EXCHECK(ex_get_attr_names(exoid, obj_types[i], ids[obj], attr_names),
                  "Could not read attributes names.\n");
          EXCHECK(ex_get_attr(exoid, obj_types[i], ids[obj], attr),
                  "Could not read attribute values.\n");

          fprintf(stdout, "\n      Attributes:\n      ID ");
          for (j = 0; j < num_attrs; ++j)
            fprintf(stdout, " %s", attr_names[j]);
          fprintf(stdout, "\n");
          for (j = 0; j < num_entries; ++j) {
            int k;
            fprintf(stdout, "      %2d ", j + 1);
            for (k = 0; k < num_attrs; ++k) {
              fprintf(stdout, " %4.1f", attr[j * num_attrs + k]);
            }
            fprintf(stdout, "\n");
          }

          for (j = 0; j < num_attrs; ++j)
            free(attr_names[j]);
          free(attr_names);
          free(attr);
        }
      }
      else if (OBJECT_IS_SET(i)) {
        int     num_df;
        int *   set_entry;
        int *   set_extra;
        double *set_df;
        EXCHECK(ex_get_set_param(exoid, obj_types[i], ids[obj], &num_entries, &num_df),
                "Could not read set parameters.\n");

        set_entry = (int *)malloc(num_entries * sizeof(int));
        set_extra = (obj_types[i] != EX_NODE_SET && obj_types[i] != EX_ELEM_SET)
                        ? (int *)malloc(num_entries * sizeof(int))
                        : 0;
        EXCHECK(ex_get_set(exoid, obj_types[i], ids[obj], set_entry, set_extra),
                "Could not read set.\n");
        fprintf(stdout, "Entries: %3d Distribution factors: %3d\n", num_entries, num_df);
        if (set_extra) {
          for (j = 0; j < num_entries; ++j)
            fprintf(stdout, "      %2d %2d\n", set_entry[j], set_extra[j]);
        }
        else {
          for (j = 0; j < num_entries; ++j)
            fprintf(stdout, "      %2d\n", set_entry[j]);
        }
        free(set_entry);
        free(set_extra);

        set_df = num_df ? (double *)malloc(num_df * sizeof(double)) : 0;
        if (set_df) {
          EXCHECK(ex_get_set_dist_fact(exoid, obj_types[i], ids[obj], set_df),
                  "Could not read set distribution factors.\n");
          fprintf(stdout, "\n    Distribution factors:\n");
          for (j = 0; j < num_df; ++j)
            fprintf(stdout, "      %4.1f\n", set_df[j]);
          free(set_df);
        }
      }
      else { /* object is map */
        int *map;
        switch (obj_types[i]) {
        case EX_NODE_MAP: num_entries = modelParams.num_nodes; break;
        case EX_EDGE_MAP: num_entries = modelParams.num_edge; break;
        case EX_FACE_MAP: num_entries = modelParams.num_face; break;
        case EX_ELEM_MAP: num_entries = modelParams.num_elem; break;
        default: num_entries          = 0;
        }
        if (num_entries) {
          fprintf(stdout, "Entries: %3d\n                :", num_entries);
          map = (int *)malloc(num_entries * sizeof(int));
          EXCHECK(ex_get_num_map(exoid, obj_types[i], ids[obj], map), "Could not read map.\n");
          for (j = 0; j < num_entries; ++j) {
            fprintf(stdout, " %d", map[j]);
          }
        }
        else {
          fprintf(stdout, "Entries: none");
        }
      }
      fprintf(stdout, "\n");

      /* Read results variables */
      if (((OBJECT_IS_BLOCK(i)) || (OBJECT_IS_SET(i))) && num_vars && num_timesteps > 0) {
        /* Print out all the time values to exercise get_var */
        entry_vals = (double *)malloc(num_entries * sizeof(double));
        for (j = 0; j < num_vars; ++j) {
          int k;
          if (!truth_tab[num_vars * obj + j])
            continue;

          fprintf(stdout, "      Variable: %s", var_names[j]);
          for (ti = 1; ti <= num_timesteps; ++ti) {
            EXCHECK(ex_get_var(exoid, ti, obj_types[i], 1 + j, ids[obj], num_entries, entry_vals),
                    "Could not read variable values.\n");

            fprintf(stdout, "\n       @t%d ", ti);
            for (k = 0; k < num_entries; ++k) {
              fprintf(stdout, " %4.1f", entry_vals[k]);
            }
          }
          fprintf(stdout, "\n");
        }
        fprintf(stdout, "\n");
        free(entry_vals);
      }
    }

    if (((OBJECT_IS_BLOCK(i)) || (OBJECT_IS_SET(i))) && num_vars && num_timesteps > 0) {
      /* Print out one element's time values to exercise get_var_time */
      entry_vals = (double *)malloc(num_timesteps * sizeof(double));
      EXCHECK(ex_inquire(exoid, obj_sizeinq[i], itmp, 0, 0), "Inquire failed.\n");
      itmp[1] = 11;
      while (itmp[1] > itmp[0])
        itmp[1] /= 2;
      for (j = 0; j < num_vars; ++j) {
        /* FIXME: This works for the dataset created by CreateEdgeFace, but not for any dataset in
         * general since
         * NULL truth table entries may mean the referenced elements don't have variable values.
         */
        EXCHECK(ex_get_var_time(exoid, obj_types[i], j + 1, itmp[1], 1, num_timesteps, entry_vals),
                "Could not read variable over time.\n");
        fprintf(stdout, "    Variable over time: %s  Entry: %3d ", var_names[j], itmp[1]);
        for (ti = 1; ti <= num_timesteps; ++ti)
          fprintf(stdout, " @t%d: %4.1f", ti, entry_vals[ti - 1]);
        fprintf(stdout, "\n");
      }
      free(entry_vals);
    }

    if (var_names) {
      for (j = 0; j < num_vars; ++j)
        free(var_names[j]);
      free(var_names);
    }
    free(truth_tab);
    free(ids);

    for (obj = 0; obj < nids; ++obj)
      free(obj_names[obj]);
    free(obj_names);

    fprintf(stdout, "\n");
  }

  EXCHECK(ex_close(exoid), "Unable to close database.\n");

  return 0;
}
Esempio n. 3
0
bool exodus_file_query(const char* filename,
                       size_t* real_size,
                       float* version,
                       int* num_mpi_processes,
                       real_array_t* times)
{
  set_ex_opts();

  if (!file_exists(filename))
    return false;

  bool valid = true;
  bool is_parallel = false;
  int my_real_size = (int)sizeof(real_t);
  int io_real_size = 0;
#if POLYMEC_HAVE_MPI
  MPI_Info info;
  MPI_Info_create(&info);
  int id = ex_open_par(filename, EX_READ, &my_real_size,
                       &io_real_size, version, 
                       MPI_COMM_WORLD, info);

  // Did that work? If not, try the serial opener.
  if (id < 0)
  {
    MPI_Info_free(&info);
    id = ex_open(filename, EX_READ, &my_real_size,
                 &io_real_size, version);
  }
  else
    is_parallel = true;
#else
  int id = ex_open(filename, EX_READ, &my_real_size,
                   &io_real_size, version);
#endif

  if (id < 0)
    valid = false;
  else
  {
    *real_size = (size_t)io_real_size;

    // Make sure that the file has 3D data.
    ex_init_params mesh_info;
    int status = ex_get_init_ext(id, &mesh_info);
    if ((status < 0) || (mesh_info.num_dim != 3))
      valid = false;
    else
    {
      // Make sure that each of the element blocks in this file have 
      // valid 3D element types.
      int num_elem_blocks = (int)mesh_info.num_elem_blk;
      int elem_block_ids[num_elem_blocks];
      ex_get_ids(id, EX_ELEM_BLOCK, elem_block_ids);
      for (int i = 0; i < num_elem_blocks; ++i)
      {
        int elem_block = elem_block_ids[i];
        char elem_type_name[MAX_NAME_LENGTH+1];
        int num_elem, num_nodes_per_elem, num_faces_per_elem;
        ex_get_block(id, EX_ELEM_BLOCK, elem_block, 
                     elem_type_name, &num_elem,
                     &num_nodes_per_elem, NULL,
                     &num_faces_per_elem, NULL);
        fe_mesh_element_t elem_type = get_element_type(elem_type_name);
        if (elem_type == FE_INVALID)
        {
          valid = false;
          break;
        }
      }
      
      if (valid)
      {
        // Query the number of processes for which this file has data.
        // Recently, we've had to add guards to check to see whether 
        // DIM_NUM_PROCS exists in the file. If it doesn't, we assume that 
        // the file corresponds to a serial data set.
        int num_proc_in_file;
        char file_type[2];
        int dim_id, status1 = nc_inq_dimid(id, DIM_NUM_PROCS, &dim_id);
        if (status1 == NC_NOERR)
        {
          ex_get_init_info(id, num_mpi_processes, &num_proc_in_file, file_type);
          if (is_parallel)
          {
            ASSERT(*num_mpi_processes == num_proc_in_file);
          }
        }
        else
        {
          *num_mpi_processes = num_proc_in_file = 1;
        }

        if (times != NULL)
        {
          // Ask for the times within the file.
          int num_times = (int)ex_inquire_int(id, EX_INQ_TIME);
          real_array_resize(times, num_times);
          if (num_times > 0)
          {
            ex_get_all_times(id, times->data);
          }
        }
      }
    }

    ex_close(id);
  }

#if POLYMEC_HAVE_MPI
  if (is_parallel)
    MPI_Info_free(&info);
#endif

  return valid;
}