int hypre_StructGridAssembleWithAP( hypre_StructGrid *grid ) { int ierr = 0; int tmp_i; int size, global_num_boxes, num_local_boxes; int i, j, d, k, index; int num_procs, myid; int *sendbuf8, *recvbuf8, *sendbuf2, *recvbuf2; int min_box_size, max_box_size; int global_min_box_size, global_max_box_size; int *ids; int max_regions, max_refinements, ologp; double gamma; hypre_Index min_index, max_index; int prune; hypre_Box *box; MPI_Comm comm = hypre_StructGridComm(grid); hypre_Box *bounding_box = hypre_StructGridBoundingBox(grid); hypre_BoxArray *local_boxes = hypre_StructGridBoxes(grid); int dim = hypre_StructGridDim(grid); hypre_BoxNeighbors *neighbors = hypre_StructGridNeighbors(grid); int max_distance = hypre_StructGridMaxDistance(grid); hypre_IndexRef periodic = hypre_StructGridPeriodic(grid); int *local_boxnums; double dbl_global_size, tmp_dbl; hypre_BoxArray *my_partition; int *part_ids, *part_boxnums; int *proc_array, proc_count, proc_alloc, count; int *tmp_proc_ids = NULL; int max_response_size; int *ap_proc_ids, *send_buf, *send_buf_starts; int *response_buf, *response_buf_starts; hypre_BoxArray *neighbor_boxes, *n_boxes_copy; int *neighbor_proc_ids, *neighbor_boxnums; int *order_index, *delete_array; int tmp_id, start, first_local; int grow, grow_array[6]; hypre_Box *grow_box; int *numghost; int ghostsize; hypre_Box *ghostbox; hypre_StructAssumedPart *assumed_part; hypre_DataExchangeResponse response_obj; int px = hypre_IndexX(periodic); int py = hypre_IndexY(periodic); int pz = hypre_IndexZ(periodic); int i_periodic = px ? 1 : 0; int j_periodic = py ? 1 : 0; int k_periodic = pz ? 1 : 0; int num_periods, multiple_ap, p; hypre_Box *result_box, *period_box; hypre_Index *pshifts; hypre_IndexRef pshift; #if NEIGH_PRINT double start_time, end_time; #endif /*--------------------------------------------- Step 1: Initializations -----------------------------------------------*/ prune = 1; /* default is to prune */ num_local_boxes = hypre_BoxArraySize(local_boxes); num_periods = (1+2*i_periodic) * (1+2*j_periodic) * (1+2*k_periodic); MPI_Comm_size(comm, &num_procs); MPI_Comm_rank(comm, &myid); /*--------------------------------------------- Step 2: Determine the global size, total number of boxes, and global bounding box. Also get the min and max box sizes since it is convenient to do so. -----------------------------------------------*/ if (neighbors == NULL) { /*these may not be needed - check later */ ids = hypre_TAlloc(int, num_local_boxes); /* for the vol and number of boxes */ sendbuf2 = hypre_CTAlloc(int, 2); recvbuf2 = hypre_CTAlloc(int, 2); size = 0; bounding_box = hypre_BoxCreate(); grow_box = hypre_BoxCreate(); if (num_local_boxes) { min_box_size = hypre_BoxVolume( hypre_BoxArrayBox(local_boxes, 0)); max_box_size = hypre_BoxVolume( hypre_BoxArrayBox(local_boxes, 0)); /* initialize min and max */ for (d=0; d<3; d++) { hypre_IndexD(min_index, d) = pow(2,30); hypre_IndexD(max_index, d) = -pow(2,30); } hypre_ForBoxI(i, local_boxes) { box = hypre_BoxArrayBox(local_boxes, i); /* get global size and number of boxes */ tmp_i = hypre_BoxVolume(box); size += tmp_i; min_box_size = hypre_min(min_box_size, tmp_i); max_box_size = hypre_max(max_box_size, tmp_i); /* set id */ ids[i] = i; /* 1/3/05 we need this for the case of holes in the domain. (I had commented it out on 12/04 - as I thought this was not necessary. */ /* zero volume boxes - still look at for getting the bounding box */ if (hypre_BoxVolume(box) == 0) /* zero volume boxes - still count */ { hypre_CopyBox(box, grow_box); for (d = 0; d < 3; d++) { if(!hypre_BoxSizeD(box, d)) { grow = (hypre_BoxIMinD(box, d) - hypre_BoxIMaxD(box, d) + 1)/2; grow_array[2*d] = grow; grow_array[2*d+1] = grow; } else { grow_array[2*d] = 0; grow_array[2*d+1] = 0; } } /* expand the box */ hypre_BoxExpand(grow_box, grow_array); box = grow_box; /*pointer copy*/ } /*now we have a vol > 0 box */ for (d = 0; d < dim; d++) /* for each dimension */ { hypre_IndexD(min_index, d) = hypre_min( hypre_IndexD(min_index, d), hypre_BoxIMinD(box, d)); hypre_IndexD(max_index, d) = hypre_max( hypre_IndexD(max_index, d), hypre_BoxIMaxD(box, d)); } }/*end for each box loop */ /* bounding box extents */ hypre_BoxSetExtents(bounding_box, min_index, max_index); }
HYPRE_Int hypre_PFMGSetup( void *pfmg_vdata, hypre_StructMatrix *A, hypre_StructVector *b, hypre_StructVector *x ) { hypre_PFMGData *pfmg_data = pfmg_vdata; MPI_Comm comm = (pfmg_data -> comm); HYPRE_Int relax_type = (pfmg_data -> relax_type); HYPRE_Int usr_jacobi_weight= (pfmg_data -> usr_jacobi_weight); double jacobi_weight = (pfmg_data -> jacobi_weight); HYPRE_Int skip_relax = (pfmg_data -> skip_relax); double *dxyz = (pfmg_data -> dxyz); HYPRE_Int rap_type; HYPRE_Int max_iter; HYPRE_Int max_levels; HYPRE_Int num_levels; hypre_Index cindex; hypre_Index findex; hypre_Index stride; hypre_Index coarsen; HYPRE_Int *cdir_l; HYPRE_Int *active_l; hypre_StructGrid **grid_l; hypre_StructGrid **P_grid_l; double *data; HYPRE_Int data_size = 0; double *relax_weights; double *mean, *deviation; double alpha, beta; hypre_StructMatrix **A_l; hypre_StructMatrix **P_l; hypre_StructMatrix **RT_l; hypre_StructVector **b_l; hypre_StructVector **x_l; /* temp vectors */ hypre_StructVector **tx_l; hypre_StructVector **r_l; hypre_StructVector **e_l; void **relax_data_l; void **matvec_data_l; void **restrict_data_l; void **interp_data_l; hypre_StructGrid *grid; HYPRE_Int dim; hypre_Box *cbox; double min_dxyz; HYPRE_Int cdir, periodic, cmaxsize; HYPRE_Int d, l; HYPRE_Int dxyz_flag; HYPRE_Int b_num_ghost[] = {0, 0, 0, 0, 0, 0}; HYPRE_Int x_num_ghost[] = {1, 1, 1, 1, 1, 1}; HYPRE_Int ierr = 0; #if DEBUG char filename[255]; #endif /*----------------------------------------------------- * Set up coarse grids *-----------------------------------------------------*/ grid = hypre_StructMatrixGrid(A); dim = hypre_StructGridDim(grid); /* Compute a new max_levels value based on the grid */ cbox = hypre_BoxDuplicate(hypre_StructGridBoundingBox(grid)); max_levels = hypre_Log2(hypre_BoxSizeD(cbox, 0)) + 2 + hypre_Log2(hypre_BoxSizeD(cbox, 1)) + 2 + hypre_Log2(hypre_BoxSizeD(cbox, 2)) + 2; if ((pfmg_data -> max_levels) > 0) { max_levels = hypre_min(max_levels, (pfmg_data -> max_levels)); } (pfmg_data -> max_levels) = max_levels; /* compute dxyz */ if ((dxyz[0] == 0) || (dxyz[1] == 0) || (dxyz[2] == 0)) { mean = hypre_CTAlloc(double, 3); deviation = hypre_CTAlloc(double, 3); hypre_PFMGComputeDxyz(A, dxyz, mean, deviation); dxyz_flag= 0; for (d = 0; d < dim; d++) { deviation[d] -= mean[d]*mean[d]; /* square of coeff. of variation */ if (deviation[d]/(mean[d]*mean[d]) > .1) { dxyz_flag= 1; break; } } hypre_TFree(mean); hypre_TFree(deviation); }
int hypre_StructCoarsen( hypre_StructGrid *fgrid, hypre_Index index, hypre_Index stride, int prune, hypre_StructGrid **cgrid_ptr ) { int ierr = 0; hypre_StructGrid *cgrid; MPI_Comm comm; int dim; hypre_BoxNeighbors *neighbors; hypre_BoxArray *hood_boxes; int num_hood; int *hood_procs; int *hood_ids; int first_local; int num_local; int num_periodic; int max_distance; hypre_Box *bounding_box; hypre_Index periodic; MPI_Request *send_requests; MPI_Status *send_status; int *send_buffer; int send_size; MPI_Request *recv_requests; MPI_Status *recv_status; int **recv_buffers; int *recv_sizes; int my_rank; int *send_procs; int *recv_procs; int num_sends; int num_recvs; hypre_BoxArray *new_hood_boxes; int new_num_hood; int *new_hood_procs; int *new_hood_ids; int new_first_local; int new_num_local; int new_num_periodic; hypre_Box *box; hypre_Box *local_box; hypre_Box *neighbor_box; hypre_Box *local_cbox; hypre_Box *neighbor_cbox; hypre_Index imin; hypre_Index imax; int alloc_size; double perimeter_count, cperimeter_count; /*double diff, distance, perimeter_count, cperimeter_count;*/ int *iarray; int *jrecv; int i, j, d, ilocal; int data_id, min_id, jj; /*----------------------------------------- * Copy needed info from fgrid *-----------------------------------------*/ comm = hypre_StructGridComm(fgrid); dim = hypre_StructGridDim(fgrid); neighbors = hypre_StructGridNeighbors(fgrid); hood_boxes = hypre_BoxArrayDuplicate(hypre_BoxNeighborsBoxes(neighbors)); num_hood = hypre_BoxArraySize(hood_boxes); iarray = hypre_BoxNeighborsProcs(neighbors); hood_procs = hypre_TAlloc(int, num_hood); for (i = 0; i < num_hood; i++) { hood_procs[i] = iarray[i]; } iarray = hypre_BoxNeighborsIDs(neighbors); hood_ids = hypre_TAlloc(int, num_hood); for (i = 0; i < num_hood; i++) { hood_ids[i] = iarray[i]; } first_local = hypre_BoxNeighborsFirstLocal(neighbors); num_local = hypre_BoxNeighborsNumLocal(neighbors); num_periodic = hypre_BoxNeighborsNumPeriodic(neighbors); max_distance = hypre_StructGridMaxDistance(fgrid); bounding_box = hypre_BoxDuplicate(hypre_StructGridBoundingBox(fgrid)); hypre_CopyIndex(hypre_StructGridPeriodic(fgrid), periodic); MPI_Comm_rank(comm, &my_rank); #if DEBUG sprintf(filename, "zcoarsen.%05d", my_rank); if ((file = fopen(filename, "a")) == NULL) { printf("Error: can't open output file %s\n", filename); exit(1); } fprintf(file, "\n\n============================\n\n"); fprintf(file, "\n\n%d\n\n", debug_count++); fprintf(file, "num_hood = %d\n", num_hood); for (i = 0; i < num_hood; i++) { box = hypre_BoxArrayBox(hood_boxes, i); fprintf(file, "(%d,%d,%d) X (%d,%d,%d) ; (%d,%d); %d\n", hypre_BoxIMinX(box),hypre_BoxIMinY(box),hypre_BoxIMinZ(box), hypre_BoxIMaxX(box),hypre_BoxIMaxY(box),hypre_BoxIMaxZ(box), hood_procs[i], hood_ids[i], hypre_BoxVolume(box)); } fprintf(file, "first_local = %d\n", first_local); fprintf(file, "num_local = %d\n", num_local); fprintf(file, "num_periodic = %d\n", num_periodic); #endif /*----------------------------------------- * Coarsen bounding box *-----------------------------------------*/ hypre_StructCoarsenBox(bounding_box, index, stride); /*----------------------------------------- * Coarsen neighborhood boxes & determine * send / recv procs * * NOTE: Currently, this always communicates * with all neighboring processes. *-----------------------------------------*/ local_cbox = hypre_BoxCreate(); neighbor_cbox = hypre_BoxCreate(); num_recvs = 0; num_sends = 0; recv_procs = NULL; send_procs = NULL; for (i = 0; i < num_hood; i++) { if (hood_procs[i] != my_rank) { for (j = 0; j < num_local; j++) { ilocal = first_local + j; local_box = hypre_BoxArrayBox(hood_boxes, ilocal); neighbor_box = hypre_BoxArrayBox(hood_boxes, i); /* coarsen boxes being considered */ hypre_CopyBox(local_box, local_cbox); hypre_StructCoarsenBox(local_cbox, index, stride); hypre_CopyBox(neighbor_box, neighbor_cbox); hypre_StructCoarsenBox(neighbor_cbox, index, stride); /*----------------------- * Receive info? *-----------------------*/ /* always communicate */ #if 0 perimeter_count = 0; cperimeter_count = 0; for (d = 0; d < 3; d++) { distance = max_distance; diff = hypre_BoxIMaxD(neighbor_box, d) - hypre_BoxIMaxD(local_box, d); if (diff > 0) { distance = hypre_min(distance, diff); } diff = hypre_BoxIMinD(local_box, d) - hypre_BoxIMinD(neighbor_box, d); if (diff > 0) { distance = hypre_min(distance, diff); } if (distance < max_distance) { perimeter_count++; } distance = max_distance; diff = hypre_BoxIMaxD(neighbor_cbox, d) - hypre_BoxIMaxD(local_cbox, d); if (diff > 0) { distance = hypre_min(distance, diff); } diff = hypre_BoxIMinD(local_cbox, d) - hypre_BoxIMinD(neighbor_cbox, d); if (diff > 0) { distance = hypre_min(distance, diff); } if (distance < max_distance) { cperimeter_count++; } } #else perimeter_count = 0; cperimeter_count = 1; #endif if (cperimeter_count > perimeter_count) { if (num_recvs == 0) { recv_procs = hypre_TAlloc(int, num_hood); recv_procs[num_recvs] = hood_procs[i]; num_recvs++; } else if (hood_procs[i] != recv_procs[num_recvs-1]) { recv_procs[num_recvs] = hood_procs[i]; num_recvs++; } } /*----------------------- * Send info? *-----------------------*/ /* always communicate */ #if 0 perimeter_count = 0; cperimeter_count = 0; for (d = 0; d < 3; d++) { distance = max_distance; diff = hypre_BoxIMaxD(local_box, d) - hypre_BoxIMaxD(neighbor_box, d); if (diff > 0) { distance = hypre_min(distance, diff); } diff = hypre_BoxIMinD(neighbor_box, d) - hypre_BoxIMinD(local_box, d); if (diff > 0) { distance = hypre_min(distance, diff); } if (distance < max_distance) { perimeter_count++; } distance = max_distance; diff = hypre_BoxIMaxD(local_cbox, d) - hypre_BoxIMaxD(neighbor_cbox, d); if (diff > 0) { distance = hypre_min(distance, diff); } diff = hypre_BoxIMinD(neighbor_cbox, d) - hypre_BoxIMinD(local_cbox, d); if (diff > 0) { distance = hypre_min(distance, diff); } if (distance < max_distance) { cperimeter_count++; } } #else perimeter_count = 0; cperimeter_count = 1; #endif if (cperimeter_count > perimeter_count) { if (num_sends == 0) { send_procs = hypre_TAlloc(int, num_hood); send_procs[num_sends] = hood_procs[i]; num_sends++; } else if (hood_procs[i] != send_procs[num_sends-1]) { send_procs[num_sends] = hood_procs[i]; num_sends++; } }