int generate_graph(Problem_Description* problem, Mesh_Description<INT>* mesh, Graph_Description<INT>* graph, Weight_Description<INT>* weight, Sphere_Info* sphere) { double time1 = get_time(); /* Find the elements surrounding a node */ if(!find_surnd_elems(mesh, graph)) { Gen_Error(0, "fatal: could not find surrounding elements"); return 0; } double time2 = get_time(); printf("Time to find surrounding elements: %fs\n", time2-time1); /* Find the adjacency, if required */ if(problem->alloc_graph == ELB_TRUE) { if(!find_adjacency(problem, mesh, graph, weight, sphere)) { Gen_Error(0, "fatal: could not find adjacency"); return 0; } time1 = get_time(); printf("Time to find the adjacency: %fs\n", time1-time2); } return 1; }
static int read_elem_info(int pexoid, int Proc, PROB_INFO_PTR prob, MESH_INFO_PTR mesh) { /* Local declarations. */ char *yo = "read_elem_info"; int iblk, ielem, inode, lnode, cnode, iplace, len; int max_nsur = 0; int i; int *nmap, *emap, *connect; int **sur_elem, *nsurnd; ELEM_INFO_PTR elements = mesh->elements; double tmp0, tmp1, tmp2; float *xptr = NULL, *yptr = NULL, *zptr = NULL; /***************************** BEGIN EXECUTION ******************************/ DEBUG_TRACE_START(Proc, yo); /* allocate memory for the global number maps */ nmap = (int *) malloc ((mesh->num_nodes + mesh->num_elems) * sizeof(int)); if (!nmap) { Gen_Error(0, "fatal: insufficient memory"); return 0; } emap = nmap + mesh->num_nodes; /* * get the global maps */ if (ex_get_elem_num_map(pexoid, emap) < 0) { Gen_Error(0, "fatal: Error returned from ex_get_elem_num_map"); return 0; } if (ex_get_node_num_map(pexoid, nmap) < 0) { Gen_Error(0, "fatal: Error returned from ex_get_node_num_map"); return 0; } /* allocate memory for the coordinates */ xptr = (float *) malloc (mesh->num_dims * mesh->num_nodes * sizeof(float)); if (!xptr) { Gen_Error(0, "fatal: insufficient memory"); return 0; } switch (mesh->num_dims) { case 3: zptr = xptr + 2 * mesh->num_nodes; /* FALLTHRU */ case 2: yptr = xptr + mesh->num_nodes; } if (ex_get_coord(pexoid, xptr, yptr, zptr) < 0) { Gen_Error(0, "fatal: Error returned from ex_get_coord"); return 0; } /* * figure out which element block needs * the most space for its connect table */ len = 0; for (iblk = 0; iblk < mesh->num_el_blks; iblk++) if ((iplace = mesh->eb_cnts[iblk] * mesh->eb_nnodes[iblk]) > len) len = iplace; connect = (int *) malloc (len * sizeof(int)); if (!connect) { Gen_Error(0, "fatal: insufficient memory"); return 0; } /***************************************************************************/ /* Fill the Connect table, Coordinates, Global Ids for each element */ /***************************************************************************/ iplace = 0; for (iblk = 0; iblk < mesh->num_el_blks; iblk++) { if (mesh->eb_cnts[iblk] > 0) { if (ex_get_elem_conn(pexoid, mesh->eb_ids[iblk], connect) < 0) { Gen_Error(0, "fatal: Error returned from ex_get_elem_conn"); return 0; } cnode = 0; for (ielem = 0; ielem < mesh->eb_cnts[iblk]; ielem++) { /* set some fields in the element structure */ elements[iplace].border = 0; elements[iplace].globalID = emap[iplace]; elements[iplace].elem_blk = iblk; elements[iplace].my_part = Proc; elements[iplace].perm_value = -1; elements[iplace].invperm_value = -1; elements[iplace].nadj = 0; elements[iplace].adj_len = 0; /* first weights are all 1 for now */ elements[iplace].cpu_wgt[0] = 1.0; if (MAX_CPU_WGTS>1){ /* second weights will be set later */ elements[iplace].cpu_wgt[1] = 0.0; /* make artificial data for more multi-weights */ for (i = 2; i < MAX_CPU_WGTS; i++) elements[iplace].cpu_wgt[i] = elements[iplace].my_part + 0.5*((elements[iplace].globalID)%i); } elements[iplace].mem_wgt = 1.0; /* allocate space for the connect list and the coordinates */ elements[iplace].connect = (int *) malloc(mesh->eb_nnodes[iblk] * sizeof(int)); if (!(elements[iplace].connect)) { Gen_Error(0, "fatal: insufficient memory"); return 0; } elements[iplace].coord = (float **) malloc(mesh->eb_nnodes[iblk] * sizeof(float *)); if (!(elements[iplace].coord)) { Gen_Error(0, "fatal: insufficient memory"); return 0; } /* save the connect table as local numbers for the moment */ tmp0 = tmp1 = tmp2 = 0.; for (inode = 0; inode < mesh->eb_nnodes[iblk]; inode++) { lnode = connect[cnode] - 1; elements[iplace].connect[inode] = lnode; cnode++; elements[iplace].coord[inode] = (float *) calloc(mesh->num_dims, sizeof(float)); if (!(elements[iplace].coord[inode])) { Gen_Error(0, "fatal: insufficient memory"); return 0; } switch (mesh->num_dims) { case 3: elements[iplace].coord[inode][2] = zptr[lnode]; tmp2 += zptr[lnode]; /* FALLTHRU */ case 2: elements[iplace].coord[inode][1] = yptr[lnode]; tmp1 += yptr[lnode]; /* FALLTHRU */ case 1: elements[iplace].coord[inode][0] = xptr[lnode]; tmp0 += xptr[lnode]; } } /* End: "for (inode = 0; inode < mesh->eb_nnodes[iblk]; inode++)" */ elements[iplace].avg_coord[0] = tmp0 / mesh->eb_nnodes[iblk]; elements[iplace].avg_coord[1] = tmp1 / mesh->eb_nnodes[iblk]; elements[iplace].avg_coord[2] = tmp2 / mesh->eb_nnodes[iblk]; iplace++; } /* End: "for (ielem = 0; ielem < mesh->eb_cnts[iblk]; ielem++)" */ } /* End: "if (mesh->eb_cnts[iblk] > 0)" */ } /* End: "for (iblk = 0; iblk < mesh->num_el_blks; iblk++)" */ /* free some memory */ free(connect); free(xptr); /*************************************************************************/ /* Find the adjacency list for each element */ /* Part one: find the surrounding elements for each node */ /*************************************************************************/ sur_elem = (int **) malloc(mesh->num_nodes * sizeof(int *)); if (!sur_elem) { Gen_Error(0, "fatal: insufficient memory"); return 0; } nsurnd = (int *) malloc(mesh->num_nodes * sizeof(int)); if (!nsurnd) { Gen_Error(0, "fatal: insufficient memory"); return 0; } if (!find_surnd_elem(mesh, sur_elem, nsurnd, &max_nsur)) { Gen_Error(0, "fatal: Error returned from find_surnd_elems"); return 0; } /*************************************************************************/ /* Part two: Find the adjacencies on this processor */ /* and get the edge weights */ /*************************************************************************/ if (!find_adjacency(Proc, mesh, sur_elem, nsurnd, max_nsur)) { Gen_Error(0, "fatal: Error returned from find_adjacency"); return 0; } /* * convert the node numbers in the connect lists to Global IDs * since they will be much easier to work with */ for (ielem = 0; ielem < mesh->num_elems; ielem++) { iblk = elements[ielem].elem_blk; for (inode = 0; inode < mesh->eb_nnodes[iblk]; inode++) { elements[ielem].connect[inode] = nmap[elements[ielem].connect[inode]]; } } /* * let cpu_wgt[1] be the number of sides (surfaces) not * connected to other elements. (useful test case for multi-weight * load balancing). */ if (MAX_CPU_WGTS>1){ for (ielem = 0; ielem < mesh->num_elems; ielem++) { elements[ielem].cpu_wgt[1] = elements[ielem].adj_len - elements[ielem].nadj; /* EBEB Strangely, nadj is often one less than expected so subtract one from the wgt to compensate. */ if (elements[ielem].cpu_wgt[1] >= 1.0) elements[ielem].cpu_wgt[1] -= 1.0; } } for (inode = 0; inode < mesh->num_nodes; inode++) free(sur_elem[inode]); free(sur_elem); free(nsurnd); free(nmap); DEBUG_TRACE_END(Proc, yo); return 1; }