int hypre_BoxArraySubtractAdjacentBoxArray( hypre_BoxArray *boxes1, hypre_BoxArray *boxes2, hypre_Box *box, int thick ) { int ierr = 0; int i; int numexp[6]; hypre_Box *box2e; hypre_Box *boxe = hypre_BoxDuplicate( box ); hypre_BoxArray *boxes2e = hypre_BoxArrayDuplicate( boxes2 ); hypre_BoxArray *tmp_box_array = hypre_BoxArrayCreate( 0 ); for ( i=0; i<6; ++i ) numexp[i] = thick; hypre_ForBoxI(i, boxes2e) { box2e = hypre_BoxArrayBox(boxes2e, i); ierr += hypre_BoxExpand( box2e, numexp ); }
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++; } }