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; }
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; }
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; }