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()-------------------------*/
int read_mesh(const std::string &exo_file, Problem_Description* problem, Mesh_Description<INT>* mesh, Weight_Description<INT>* weight ) { float version, *xptr, *yptr, *zptr; char elem_type[MAX_STR_LENGTH+1]; E_Type blk_elem_type; /*---------------------------Execution Begins--------------------------------*/ /* Open the ExodusII file */ int exoid, cpu_ws=0, io_ws=0; int mode = EX_READ | problem->int64api; if((exoid=ex_open(exo_file.c_str(), mode, &cpu_ws, &io_ws, &version)) < 0) { Gen_Error(0, "fatal: unable to open ExodusII mesh file"); return 0; } /* Read the coordinates, if desired */ xptr = yptr = zptr = NULL; if(problem->read_coords == ELB_TRUE) { switch(mesh->num_dims) { case 3: zptr = (mesh->coords)+2*(mesh->num_nodes); /* FALLTHRU */ case 2: yptr = (mesh->coords)+(mesh->num_nodes); /* FALLTHRU */ case 1: xptr = mesh->coords; } if(ex_get_coord(exoid, xptr, yptr, zptr) < 0) { Gen_Error(0, "fatal: unable to read coordinate values for mesh"); return 0; } } /* End "if(problem->read_coords == ELB_TRUE)" */ /* Read the element block IDs */ std::vector<INT> el_blk_ids(mesh->num_el_blks); std::vector<INT> el_blk_cnts(mesh->num_el_blks); if(ex_get_elem_blk_ids(exoid, &el_blk_ids[0]) < 0) { Gen_Error(0, "fatal: unable to read element block IDs"); return 0; } /* Read the element connectivity */ size_t gelem_cnt=0; for(size_t cnt=0; cnt < mesh->num_el_blks; cnt++) { INT nodes_per_elem, num_attr; if(ex_get_elem_block(exoid, el_blk_ids[cnt], elem_type, &(el_blk_cnts[cnt]), &nodes_per_elem, &num_attr) < 0) { Gen_Error(0, "fatal: unable to read element block"); return 0; } blk_elem_type = get_elem_type(elem_type, nodes_per_elem, mesh->num_dims); INT *blk_connect = (INT*)malloc(sizeof(INT)*el_blk_cnts[cnt]*nodes_per_elem); if(!blk_connect) { Gen_Error(0, "fatal: insufficient memory"); return 0; } /* Get the connectivity for this element block */ if(ex_get_elem_conn(exoid, el_blk_ids[cnt], blk_connect) < 0) { Gen_Error(0, "fatal: failed to get element connectivity"); return 0; } /* find out if this element block is weighted */ int wgt = -1; if (weight->type & EL_BLK) wgt = in_list(el_blk_ids[cnt], weight->elemblk); /* Fill the 2D global connectivity array */ if (((problem->type == ELEMENTAL) && (weight->type & EL_BLK)) || ((problem->type == NODAL) && (weight->type & EL_BLK))) { for(int64_t cnt2=0; cnt2 < el_blk_cnts[cnt]; cnt2++) { mesh->elem_type[gelem_cnt] = blk_elem_type; /* while going through the blocks, take care of the weighting */ if ((problem->type == ELEMENTAL) && (weight->type & EL_BLK)) { /* is this block weighted */ if (wgt >= 0) { /* check if there is a read value */ if (weight->vertices[gelem_cnt] >= 1) { /* and if it should be overwritten */ if (weight->ow_read) weight->vertices[gelem_cnt] = weight->elemblk_wgt[wgt]; } else weight->vertices[gelem_cnt] = weight->elemblk_wgt[wgt]; } else { /* now check if this weight has been initialized */ if (weight->vertices[gelem_cnt] < 1) weight->vertices[gelem_cnt] = 1; } } for(int64_t cnt3=0; cnt3 < nodes_per_elem; cnt3++) { INT node = blk_connect[cnt3 + cnt2*nodes_per_elem] - 1; assert(node >= 0); mesh->connect[gelem_cnt][cnt3] = node; /* deal with the weighting if necessary */ if ((problem->type == NODAL) && (weight->type & EL_BLK)) { /* is this block weighted */ if (wgt >= 0) { /* check if I read an exodus file */ if (weight->type & READ_EXO) { /* check if it can be overwritten */ if (weight->ow_read) { /* check if it has been overwritten already */ if (weight->ow[node]) { weight->vertices[node] = MAX(weight->vertices[node], weight->elemblk_wgt[wgt]); } else { weight->vertices[node] = weight->elemblk_wgt[wgt]; weight->ow[node] = 1; /* read value has been overwritten */ } } } else { weight->vertices[node] = MAX(weight->vertices[node], weight->elemblk_wgt[wgt]); } } else { /* now check if this weight has been initialized */ if (weight->vertices[node] < 1) weight->vertices[node] = 1; } } } gelem_cnt++; } } else { // No weights... for (int64_t cnt2=0; cnt2 < el_blk_cnts[cnt]; cnt2++) { mesh->elem_type[gelem_cnt] = blk_elem_type; for (int64_t cnt3=0; cnt3 < nodes_per_elem; cnt3++) { INT node = blk_connect[cnt2*nodes_per_elem + cnt3] - 1; assert(node >= 0); mesh->connect[gelem_cnt][cnt3] = node; } gelem_cnt++; } } /* Free up memory */ free(blk_connect); } /* End "for(cnt=0; cnt < mesh->num_el_blks; cnt++)" */ /* if there is a group designator, then parse it here */ if (problem->groups != NULL) { if (!parse_groups(&el_blk_ids[0], &el_blk_cnts[0], mesh, problem)) { Gen_Error(0, "fatal: unable to parse group designator"); ex_close(exoid); return 0; } } else problem->num_groups = 1; /* there is always one group */ /* Close the ExodusII file */ if(ex_close(exoid) < 0) Gen_Error(0, "warning: failed to close ExodusII mesh file"); return 1; } /*---------------------------End read_mesh()-------------------------------*/
int 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 */ }