int hypre_SMGRelaxSetupBaseBoxArray( void *relax_vdata, hypre_StructMatrix *A, hypre_StructVector *b, hypre_StructVector *x ) { hypre_SMGRelaxData *relax_data = relax_vdata; hypre_StructGrid *grid; hypre_BoxArray *boxes; hypre_BoxArray *base_box_array; int ierr = 0; grid = hypre_StructVectorGrid(x); boxes = hypre_StructGridBoxes(grid); base_box_array = hypre_BoxArrayDuplicate(boxes); hypre_ProjectBoxArray(base_box_array, (relax_data -> base_index), (relax_data -> base_stride)); (relax_data -> base_box_array) = base_box_array; return ierr; }
HYPRE_Int hypre_SMGResidualSetup( void *residual_vdata, hypre_StructMatrix *A, hypre_StructVector *x, hypre_StructVector *b, hypre_StructVector *r ) { HYPRE_Int ierr = 0; hypre_SMGResidualData *residual_data = residual_vdata; hypre_IndexRef base_index = (residual_data -> base_index); hypre_IndexRef base_stride = (residual_data -> base_stride); hypre_StructGrid *grid; hypre_StructStencil *stencil; hypre_BoxArray *base_points; hypre_ComputeInfo *compute_info; hypre_ComputePkg *compute_pkg; /*---------------------------------------------------------- * Set up base points and the compute package *----------------------------------------------------------*/ grid = hypre_StructMatrixGrid(A); stencil = hypre_StructMatrixStencil(A); base_points = hypre_BoxArrayDuplicate(hypre_StructGridBoxes(grid)); hypre_ProjectBoxArray(base_points, base_index, base_stride); hypre_CreateComputeInfo(grid, stencil, &compute_info); hypre_ComputeInfoProjectComp(compute_info, base_index, base_stride); hypre_ComputePkgCreate(compute_info, hypre_StructVectorDataSpace(x), 1, grid, &compute_pkg); /*---------------------------------------------------------- * Set up the residual data structure *----------------------------------------------------------*/ (residual_data -> A) = hypre_StructMatrixRef(A); (residual_data -> x) = hypre_StructVectorRef(x); (residual_data -> b) = hypre_StructVectorRef(b); (residual_data -> r) = hypre_StructVectorRef(r); (residual_data -> base_points) = base_points; (residual_data -> compute_pkg) = compute_pkg; /*----------------------------------------------------- * Compute flops *-----------------------------------------------------*/ (residual_data -> flops) = (hypre_StructMatrixGlobalSize(A) + hypre_StructVectorGlobalSize(x)) / (hypre_IndexX(base_stride) * hypre_IndexY(base_stride) * hypre_IndexZ(base_stride) ); return ierr; }
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 ); }
int hypre_SMGResidualSetup(void *residual_vdata,hypre_StructMatrix *A,hypre_StructVector *x,hypre_StructVector *b,hypre_StructVector *r) { int ierr = 0; hypre_SMGResidualData *residual_data = residual_vdata; hypre_IndexRef base_index = (residual_data -> base_index); hypre_IndexRef base_stride = (residual_data -> base_stride); hypre_Index unit_stride; hypre_StructGrid *grid; hypre_StructStencil *stencil; hypre_BoxArrayArray *send_boxes; hypre_BoxArrayArray *recv_boxes; int **send_processes; int **recv_processes; hypre_BoxArrayArray *indt_boxes; hypre_BoxArrayArray *dept_boxes; hypre_BoxArray *base_points; hypre_ComputePkg *compute_pkg; /*---------------------------------------------------------- * Set up base points and the compute package *----------------------------------------------------------*/ grid = (A -> grid); stencil = (A -> stencil); ((((unit_stride[0] = 1) , (unit_stride[1] = 1))) , (unit_stride[2] = 1)); base_points = hypre_BoxArrayDuplicate((grid -> boxes)); hypre_ProjectBoxArray(base_points,base_index,base_stride); hypre_CreateComputeInfo(grid,stencil,&send_boxes,&recv_boxes,&send_processes,&recv_processes,&indt_boxes,&dept_boxes); hypre_ProjectBoxArrayArray(indt_boxes,base_index,base_stride); hypre_ProjectBoxArrayArray(dept_boxes,base_index,base_stride); hypre_ComputePkgCreate(send_boxes,recv_boxes,unit_stride,unit_stride,send_processes,recv_processes,indt_boxes,dept_boxes,base_stride,grid,(x -> data_space),1,&compute_pkg); /*---------------------------------------------------------- * Set up the residual data structure *----------------------------------------------------------*/ residual_data -> A = hypre_StructMatrixRef(A); residual_data -> x = hypre_StructVectorRef(x); residual_data -> b = hypre_StructVectorRef(b); residual_data -> r = hypre_StructVectorRef(r); residual_data -> base_points = base_points; residual_data -> compute_pkg = compute_pkg; /*----------------------------------------------------- * Compute flops *-----------------------------------------------------*/ residual_data -> flops = (((A -> global_size) + (x -> global_size)) / (((base_stride[0]) * (base_stride[1])) * (base_stride[2]))); return ierr; }
HYPRE_Int hypre_StructCoarsen( hypre_StructGrid *fgrid, hypre_Index index, hypre_Index stride, HYPRE_Int prune, hypre_StructGrid **cgrid_ptr ) { hypre_StructGrid *cgrid; MPI_Comm comm; HYPRE_Int ndim; hypre_BoxArray *my_boxes; hypre_Index periodic; hypre_Index ilower, iupper; hypre_Box *box; hypre_Box *new_box; hypre_Box *bounding_box; HYPRE_Int i, j, myid, count; HYPRE_Int info_size, max_nentries; HYPRE_Int num_entries; HYPRE_Int *fids, *cids; hypre_Index new_dist; hypre_IndexRef max_distance; HYPRE_Int proc, id; HYPRE_Int coarsen_factor, known; HYPRE_Int num, last_proc; #if 0 hypre_StructAssumedPart *fap = NULL, *cap = NULL; #endif hypre_BoxManager *fboxman, *cboxman; hypre_BoxManEntry *entries; hypre_BoxManEntry *entry; void *entry_info = NULL; #if TIME_DEBUG HYPRE_Int tindex; char new_title[80]; hypre_sprintf(new_title,"Coarsen.%d",s_coarsen_num); tindex = hypre_InitializeTiming(new_title); s_coarsen_num++; hypre_BeginTiming(tindex); #endif hypre_SetIndex(ilower, 0); hypre_SetIndex(iupper, 0); /* get relevant information from the fine grid */ fids = hypre_StructGridIDs(fgrid); fboxman = hypre_StructGridBoxMan(fgrid); comm = hypre_StructGridComm(fgrid); ndim = hypre_StructGridNDim(fgrid); max_distance = hypre_StructGridMaxDistance(fgrid); /* initial */ hypre_MPI_Comm_rank(comm, &myid ); /* create new coarse grid */ hypre_StructGridCreate(comm, ndim, &cgrid); /* coarsen my boxes and create the coarse grid ids (same as fgrid) */ my_boxes = hypre_BoxArrayDuplicate(hypre_StructGridBoxes(fgrid)); cids = hypre_TAlloc(HYPRE_Int, hypre_BoxArraySize(my_boxes)); for (i = 0; i < hypre_BoxArraySize(my_boxes); i++) { box = hypre_BoxArrayBox(my_boxes, i); hypre_StructCoarsenBox(box, index, stride); cids[i] = fids[i]; } /* prune? */ /* zero volume boxes are needed when forming P and P^T */ if (prune) { count = 0; hypre_ForBoxI(i, my_boxes) { box = hypre_BoxArrayBox(my_boxes, i); if (hypre_BoxVolume(box)) { hypre_CopyBox(box, hypre_BoxArrayBox(my_boxes, count)); cids[count] = cids[i]; count++; } } hypre_BoxArraySetSize(my_boxes, count); }
int hypre_SMGResidualSetup( void *residual_vdata, hypre_StructMatrix *A, hypre_StructVector *x, hypre_StructVector *b, hypre_StructVector *r ) { int ierr = 0; hypre_SMGResidualData *residual_data = residual_vdata; hypre_IndexRef base_index = (residual_data -> base_index); hypre_IndexRef base_stride = (residual_data -> base_stride); hypre_Index unit_stride; hypre_StructGrid *grid; hypre_StructStencil *stencil; hypre_BoxArrayArray *send_boxes; hypre_BoxArrayArray *recv_boxes; int **send_processes; int **recv_processes; hypre_BoxArrayArray *indt_boxes; hypre_BoxArrayArray *dept_boxes; hypre_BoxArray *base_points; hypre_ComputePkg *compute_pkg; /*---------------------------------------------------------- * Set up base points and the compute package *----------------------------------------------------------*/ grid = hypre_StructMatrixGrid(A); stencil = hypre_StructMatrixStencil(A); hypre_SetIndex(unit_stride, 1, 1, 1); base_points = hypre_BoxArrayDuplicate(hypre_StructGridBoxes(grid)); hypre_ProjectBoxArray(base_points, base_index, base_stride); hypre_CreateComputeInfo(grid, stencil, &send_boxes, &recv_boxes, &send_processes, &recv_processes, &indt_boxes, &dept_boxes); hypre_ProjectBoxArrayArray(indt_boxes, base_index, base_stride); hypre_ProjectBoxArrayArray(dept_boxes, base_index, base_stride); hypre_ComputePkgCreate(send_boxes, recv_boxes, unit_stride, unit_stride, send_processes, recv_processes, indt_boxes, dept_boxes, base_stride, grid, hypre_StructVectorDataSpace(x), 1, &compute_pkg); /*---------------------------------------------------------- * Set up the residual data structure *----------------------------------------------------------*/ (residual_data -> A) = hypre_StructMatrixRef(A); (residual_data -> x) = hypre_StructVectorRef(x); (residual_data -> b) = hypre_StructVectorRef(b); (residual_data -> r) = hypre_StructVectorRef(r); (residual_data -> base_points) = base_points; (residual_data -> compute_pkg) = compute_pkg; /*----------------------------------------------------- * Compute flops *-----------------------------------------------------*/ (residual_data -> flops) = (hypre_StructMatrixGlobalSize(A) + hypre_StructVectorGlobalSize(x)) / (hypre_IndexX(base_stride) * hypre_IndexY(base_stride) * hypre_IndexZ(base_stride) ); return ierr; }
hypre_StructMatrix * hypre_StructMatrixCreateMask( hypre_StructMatrix *matrix, int num_stencil_indices, int *stencil_indices ) { hypre_StructMatrix *mask; hypre_StructStencil *stencil; hypre_Index *stencil_shape; int stencil_size; hypre_Index *mask_stencil_shape; int mask_stencil_size; hypre_BoxArray *data_space; int **data_indices; int **mask_data_indices; int i, j; stencil = hypre_StructMatrixStencil(matrix); stencil_shape = hypre_StructStencilShape(stencil); stencil_size = hypre_StructStencilSize(stencil); mask = hypre_CTAlloc(hypre_StructMatrix, 1); hypre_StructMatrixComm(mask) = hypre_StructMatrixComm(matrix); hypre_StructGridRef(hypre_StructMatrixGrid(matrix), &hypre_StructMatrixGrid(mask)); hypre_StructMatrixUserStencil(mask) = hypre_StructStencilRef(hypre_StructMatrixUserStencil(matrix)); mask_stencil_size = num_stencil_indices; mask_stencil_shape = hypre_CTAlloc(hypre_Index, num_stencil_indices); for (i = 0; i < num_stencil_indices; i++) { hypre_CopyIndex(stencil_shape[stencil_indices[i]], mask_stencil_shape[i]); } hypre_StructMatrixStencil(mask) = hypre_StructStencilCreate(hypre_StructStencilDim(stencil), mask_stencil_size, mask_stencil_shape); hypre_StructMatrixNumValues(mask) = hypre_StructMatrixNumValues(matrix); hypre_StructMatrixDataSpace(mask) = hypre_BoxArrayDuplicate(hypre_StructMatrixDataSpace(matrix)); hypre_StructMatrixData(mask) = hypre_StructMatrixData(matrix); hypre_StructMatrixDataAlloced(mask) = 0; hypre_StructMatrixDataSize(mask) = hypre_StructMatrixDataSize(matrix); data_space = hypre_StructMatrixDataSpace(matrix); data_indices = hypre_StructMatrixDataIndices(matrix); mask_data_indices = hypre_CTAlloc(int *, hypre_BoxArraySize(data_space)); hypre_ForBoxI(i, data_space) { mask_data_indices[i] = hypre_TAlloc(int, num_stencil_indices); for (j = 0; j < num_stencil_indices; j++) { mask_data_indices[i][j] = data_indices[i][stencil_indices[j]]; } }
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++; } }