int ne_test_gecm(int fileid) { int i, j, iproc, error; int elem_ids[ECNTCM], elem_map_cnts[NECMAP], proc_ids[ECNTCM]; int side_ids[ECNTCM], elem_map_ids[NECMAP]; /*-----------------------------Execution Begins-----------------------------*/ for(iproc=0; iproc < NPROCF; iproc++) { error = ne_get_cmap_params(fileid, NULL, NULL, elem_map_ids, elem_map_cnts, iproc); if (error < 0) return error; for(i=0; i < NECMAP; i++) { error = ne_get_elem_cmap(fileid, elem_map_ids[i], elem_ids, side_ids, proc_ids, iproc); if (error < 0) return error; for(j=0; j < ECNTCM; j++) { if (elem_ids[j] != 2*(j+1)) return -1; if (side_ids[j] != 3*(j+1)) return -1; if (proc_ids[j] != 4*(j+1)) return -1; } } } return 0; }
int ne_test_gncm(int fileid) { int i, j, iproc, error; int node_map_ids[NNCMAP], node_map_cnts[NNCMAP]; int node_ids[NCNTCM], proc_ids[NCNTCM]; /*-----------------------------Execution Begins-----------------------------*/ for(iproc=0; iproc < NPROCF; iproc++) { error = ne_get_cmap_params(fileid, node_map_ids, node_map_cnts, NULL, NULL, iproc); if (error < 0) return error; for(i=0; i < NNCMAP; i++) { error = ne_get_node_cmap(fileid, node_map_ids[i], node_ids, proc_ids, iproc); if (error < 0) return error; for(j=0; j < NCNTCM; j++) { if (node_ids[j] != 2*(j+1)) return -1; if (proc_ids[j] != 3*(j+1)) return -1; } } } return 0; }
static int read_comm_map_info(int pexoid, int Proc, PROB_INFO_PTR prob, MESH_INFO_PTR mesh) { /* Local declarations. */ char *yo = "read_comm_map_info"; int ielem, imap, loc_elem, iblk, max_len, offset, index; int nnodei, nnodeb, nnodee, nelemi, nelemb, nncmap; int *int_elem, *bor_elem; int *proc_ids; int *gids, *my_procs, *recv_procs; int ierr, nrecv; int msg = 200; int sid; ELEM_INFO_PTR elements = mesh->elements; ZOLTAN_COMM_OBJ *comm_obj; E_Type etype; /***************************** BEGIN EXECUTION ******************************/ DEBUG_TRACE_START(Proc, yo); if (ne_get_loadbal_param(pexoid, &nnodei, &nnodeb, &nnodee, &nelemi, &nelemb, &nncmap, &(mesh->necmap), Proc) < 0) { Gen_Error(0, "fatal: Error returned from ne_get_loadbal_param"); return 0; } /* * get the list of the border elements in order to set * the border flag in the element structures */ int_elem = (int *) malloc ((nelemi + nelemb) * sizeof(int)); if (!int_elem) { Gen_Error(0, "fatal: insufficient memory"); return 0; } bor_elem = int_elem + nelemi; if (ne_get_elem_map(pexoid, int_elem, bor_elem, Proc) < 0) { Gen_Error(0, "fatal: Error returned from ne_get_elem_map"); return 0; } for (ielem = 0; ielem < nelemb; ielem++) { elements[bor_elem[ielem]-1].border = 1; } free(int_elem); /* * For now, only get the elemental communication maps, * since, in the driver, elements are only considered * adjacent if they share a face (same definition used * in element communication maps). Eventually, the ability * to consider elements that are connected by any nodes * adjacent will have to be added. When that happens, * the nodal communication maps will be needed. */ mesh->ecmap_cnt = (int *) malloc (mesh->necmap * sizeof(int)); mesh->ecmap_id = (int *) malloc(mesh->necmap * sizeof(int)); if (!mesh->ecmap_cnt || !mesh->ecmap_id) { Gen_Error(0, "fatal: insufficient memory"); return 0; } if (ne_get_cmap_params(pexoid, NULL, NULL, mesh->ecmap_id, mesh->ecmap_cnt, Proc) < 0) { Gen_Error(0, "fatal: Error returned from ne_get_cmap_params"); return 0; } max_len = 0; for (imap = 0; imap < mesh->necmap; imap++) max_len += mesh->ecmap_cnt[imap]; proc_ids = (int *) malloc(4 * max_len * sizeof(int)); gids = proc_ids + max_len; my_procs = gids + max_len; recv_procs = my_procs + max_len; mesh->ecmap_elemids = (int *) malloc(max_len * sizeof(int)); mesh->ecmap_sideids = (int *) malloc(max_len * sizeof(int)); mesh->ecmap_neighids = (int *) malloc(max_len * sizeof(int)); if (!mesh->ecmap_elemids || !mesh->ecmap_sideids || !mesh->ecmap_neighids) { Gen_Error(0, "fatal: insufficient memory"); return 0; } offset = 0; for (imap = 0; imap < mesh->necmap; imap++) { if(ne_get_elem_cmap(pexoid, mesh->ecmap_id[imap], &(mesh->ecmap_elemids[offset]), &(mesh->ecmap_sideids[offset]), &(proc_ids[offset]), Proc) < 0) { Gen_Error(0, "fatal: Error returned from ne_get_elem_cmap"); return 0; } offset += mesh->ecmap_cnt[imap]; } /* End: "for (imap = 0; imap < mesh->necmap; imap++)" */ /* * Decrement the ecmap_elemids by one for zero-based local numbering. * Convert the element ids to global ids to send to * the neighboring processor. */ for (ielem = 0; ielem < max_len; ielem++) { mesh->ecmap_elemids[ielem]--; gids[ielem] = elements[mesh->ecmap_elemids[ielem]].globalID; my_procs[ielem] = Proc; } /* * Now communicate with other processor to get global IDs * for the adjacent elements in this communication map. */ ierr = Zoltan_Comm_Create(&comm_obj, max_len, proc_ids, MPI_COMM_WORLD, msg, &nrecv); if (ierr != ZOLTAN_OK) { Gen_Error(0, "fatal: Error returned from Zoltan_Comm_Create"); return 0; } if (nrecv != max_len) { /* Sanity check; this should never happen. */ Gen_Error(0, "fatal: Error returned from Zoltan_Comm_Create"); return 0; } /* Exchange ids to neighbors. * Assuming messages will be stored in order of processor number in * ecmap_neighids. */ ierr = Zoltan_Comm_Do(comm_obj, msg+1, (char *) gids, sizeof(int), (char *) (mesh->ecmap_neighids)); /* Exchange sanity check information. * Allows to check assumption that messages are stored in order of * processor number. */ if (ierr == ZOLTAN_OK) ierr = Zoltan_Comm_Do(comm_obj, msg+2, (char *) my_procs, sizeof(int), (char *) recv_procs); if (ierr != ZOLTAN_OK) { Gen_Error(0, "fatal: Error returned from Zoltan_Comm_Do"); return 0; } ierr = Zoltan_Comm_Destroy(&comm_obj); /* Sanity check: messages stored in order of processor number. */ for (ielem = 0; ielem < max_len; ielem++) { if (proc_ids[ielem] != recv_procs[ielem]) { Gen_Error(0, "fatal: Sanity check failed; assumption wrong"); return 0; } } /* now process all of the element ids that have been received */ offset = 0; for (imap = 0; imap < mesh->necmap; imap++) { for (ielem = 0; ielem < mesh->ecmap_cnt[imap]; ielem++) { index = ielem + offset; /* translate from element id in the communication map to local elem id */ loc_elem = mesh->ecmap_elemids[index]; iblk = elements[loc_elem].elem_blk; etype = (E_Type) (mesh->eb_etypes[iblk]); (elements[loc_elem].nadj)++; if(elements[loc_elem].nadj > elements[loc_elem].adj_len) { /* Shouldn't happen as long as only side adjacencies are used. */ /* adj_len == number of sides. */ /* Space should already be allocated for the adjacencies read */ /* from the communication maps. */ Gen_Error(0, "fatal: Number of adj greater than adj_len"); return 0; } /* Store adjacency info in the adj entry corresponding to this side. */ sid = mesh->ecmap_sideids[index] - 1; elements[loc_elem].adj[sid] = mesh->ecmap_neighids[index]; elements[loc_elem].adj_proc[sid] = mesh->ecmap_id[imap]; elements[loc_elem].edge_wgt[sid] = (float) get_elem_info(NSNODES, etype, mesh->ecmap_sideids[index]); } /* End: "for (ielem = 0; ielem < mesh->ecmap_cnt[imap]; ielem++)" */ offset += mesh->ecmap_cnt[imap]; } /* End: "for for (imap = 0; imap < mesh->necmap; imap++)" */ free (proc_ids); DEBUG_TRACE_END(Proc, yo); return 1; }