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); }
/*-------------------------------------------------------------------------- * hypre_CF_StenBox: Given a cgrid_box, a fgrid_box, and a stencil_shape, * the stencil_shape direction. Returns an empty box if these two boxes * are not connected in the stencil_shape direction. *--------------------------------------------------------------------------*/ hypre_Box * hypre_CF_StenBox( hypre_Box *fgrid_box, hypre_Box *cgrid_box, hypre_Index stencil_shape, hypre_Index rfactors, HYPRE_Int ndim ) { hypre_Box coarsen_box; hypre_Box contracted_box; hypre_Box extended_box; hypre_Box intersect_box; hypre_Box *stenbox; hypre_Box shift_cbox, shift_ibox; hypre_Index size_cbox, size_ibox; hypre_Index temp_index; hypre_Index shift_index; HYPRE_Int i, remainder, intersect_size; hypre_ClearIndex(temp_index); stenbox = hypre_BoxCreate(); /*-------------------------------------------------------------------------- * Coarsen the fine box, extend it, and shift it to determine if there * is a reach between fgrid_box and cgrid_box in the stencil_shape direction. * Note: the fine_box may not align as the index rule assumes: * [a_0,a_1,a_2]x[b_0,b_1,b_2], a_i= c_i*rfactors[i] * b_i= f_i*rfactors[i]+g_i, g_i= rfactors[i]-1. * When fine_box does not, then there must be a sibling box. fine_box * should be adjusted so that the flooring of the MapFineToCoarse does not * introduce extra coarse nodes in the coarsened box. Only the lower bound * needs to be adjusted. *--------------------------------------------------------------------------*/ hypre_CopyBox(fgrid_box, &contracted_box); for (i= 0; i< ndim; i++) { remainder= hypre_BoxIMin(&contracted_box)[i] % rfactors[i]; if (remainder) { hypre_BoxIMin(&contracted_box)[i]+= rfactors[i] - remainder; } } hypre_StructMapFineToCoarse(hypre_BoxIMin(&contracted_box), temp_index, rfactors, hypre_BoxIMin(&coarsen_box)); hypre_StructMapFineToCoarse(hypre_BoxIMax(&contracted_box), temp_index, rfactors, hypre_BoxIMax(&coarsen_box)); hypre_ClearIndex(size_cbox); for (i= 0; i< ndim; i++) { size_cbox[i] = hypre_BoxSizeD(&coarsen_box, i) - 1; } /*--------------------------------------------------------------------- * Extend the coarsened fgrid_box by one layer in each direction so * that actual cf interface is reached. If only coarsen_box were * extended, the actual cf interface may not be reached. *---------------------------------------------------------------------*/ hypre_CopyBox(&coarsen_box, &extended_box); /*hypre_StructMapFineToCoarse(hypre_BoxIMin(fgrid_box), temp_index, rfactors, hypre_BoxIMin(&extended_box)); hypre_StructMapFineToCoarse(hypre_BoxIMax(fgrid_box), temp_index, rfactors, hypre_BoxIMax(&extended_box));*/ for (i= 0; i< ndim; i++) { hypre_BoxIMin(&extended_box)[i]-=1; hypre_BoxIMax(&extended_box)[i]+=1; } hypre_IntersectBoxes(&extended_box, cgrid_box, &intersect_box); intersect_size= hypre_BoxVolume(&intersect_box); if (intersect_size == 0) { hypre_CopyBox(&intersect_box, stenbox); return stenbox; } hypre_ClearIndex(size_ibox); for (i= 0; i< ndim; i++) { size_ibox[i] = hypre_BoxSizeD(&intersect_box, i) - 1; } /*--------------------------------------------------------------------- * To find the box extents that must be loop over, we need to take the * "opposite" stencil_shape and shift the coarsen and extended boxes. *---------------------------------------------------------------------*/ hypre_SetIndex(shift_index, -size_ibox[0]*stencil_shape[0], -size_ibox[1]*stencil_shape[1], -size_ibox[2]*stencil_shape[2]); hypre_AddIndex(shift_index, hypre_BoxIMin(&intersect_box), hypre_BoxIMin(&shift_ibox)); hypre_AddIndex(shift_index, hypre_BoxIMax(&intersect_box), hypre_BoxIMax(&shift_ibox)); hypre_IntersectBoxes(&shift_ibox, &intersect_box, &shift_ibox); hypre_SetIndex(shift_index, -size_cbox[0]*stencil_shape[0], -size_cbox[1]*stencil_shape[1], -size_cbox[2]*stencil_shape[2]); hypre_AddIndex(shift_index, hypre_BoxIMin(&coarsen_box), hypre_BoxIMin(&shift_cbox)); hypre_AddIndex(shift_index, hypre_BoxIMax(&coarsen_box), hypre_BoxIMax(&shift_cbox)); hypre_IntersectBoxes(&shift_cbox, &coarsen_box, &shift_cbox); /*--------------------------------------------------------------------- * shift_ibox & shift_cbox will contain the loop extents. Shifting * shift_cbox by -stencil_shape and then intersecting with shift_ibox * gives the exact extents. *---------------------------------------------------------------------*/ hypre_SetIndex(shift_index, -stencil_shape[0], -stencil_shape[1], -stencil_shape[2]); hypre_AddIndex(shift_index, hypre_BoxIMin(&shift_cbox), hypre_BoxIMin(&shift_cbox)); hypre_AddIndex(shift_index, hypre_BoxIMax(&shift_cbox), hypre_BoxIMax(&shift_cbox)); hypre_IntersectBoxes(&shift_cbox, &shift_ibox, stenbox); return stenbox; }