HYPRE_Int hypre_BoxBoundaryIntersect( hypre_Box *box, hypre_StructGrid *grid, HYPRE_Int d, HYPRE_Int dir, hypre_BoxArray *boundary ) { HYPRE_Int ndim = hypre_BoxNDim(box); hypre_BoxManager *boxman; hypre_BoxManEntry **entries; hypre_BoxArray *int_boxes, *tmp_boxes; hypre_Box *bbox, *ibox; HYPRE_Int nentries, i; /* set bbox to the box surface of interest */ hypre_BoxArraySetSize(boundary, 1); bbox = hypre_BoxArrayBox(boundary, 0); hypre_CopyBox(box, bbox); if (dir > 0) { hypre_BoxIMinD(bbox, d) = hypre_BoxIMaxD(bbox, d); } else if (dir < 0) { hypre_BoxIMaxD(bbox, d) = hypre_BoxIMinD(bbox, d); } /* temporarily shift bbox in direction dir and intersect with the grid */ hypre_BoxIMinD(bbox, d) += dir; hypre_BoxIMaxD(bbox, d) += dir; boxman = hypre_StructGridBoxMan(grid); hypre_BoxManIntersect(boxman, hypre_BoxIMin(bbox), hypre_BoxIMax(bbox), &entries, &nentries); hypre_BoxIMinD(bbox, d) -= dir; hypre_BoxIMaxD(bbox, d) -= dir; /* shift intersected boxes in direction -dir and subtract from bbox */ int_boxes = hypre_BoxArrayCreate(nentries, ndim); tmp_boxes = hypre_BoxArrayCreate(0, ndim); for (i = 0; i < nentries; i++) { ibox = hypre_BoxArrayBox(int_boxes, i); hypre_BoxManEntryGetExtents( entries[i], hypre_BoxIMin(ibox), hypre_BoxIMax(ibox)); hypre_BoxIMinD(ibox, d) -= dir; hypre_BoxIMaxD(ibox, d) -= dir; } hypre_SubtractBoxArrays(boundary, int_boxes, tmp_boxes); hypre_BoxArrayDestroy(int_boxes); hypre_BoxArrayDestroy(tmp_boxes); hypre_TFree(entries); return hypre_error_flag; }
HYPRE_Int AddValuesVector( hypre_StructGrid *grid, hypre_StructVector *vector, HYPRE_Real value ) { HYPRE_Int ierr = 0; hypre_BoxArray *gridboxes; HYPRE_Int i,ib; hypre_IndexRef ilower; hypre_IndexRef iupper; hypre_Box *box; HYPRE_Real *values; HYPRE_Int volume,dim; gridboxes = hypre_StructGridBoxes(grid); dim = hypre_StructGridNDim(grid); ib=0; hypre_ForBoxI(ib, gridboxes) { box = hypre_BoxArrayBox(gridboxes, ib); volume = hypre_BoxVolume(box); values = hypre_CTAlloc(HYPRE_Real, volume); for (i = 0; i < volume; i++) { values[i] = value; } ilower = hypre_BoxIMin(box); iupper = hypre_BoxIMax(box); HYPRE_StructVectorSetBoxValues(vector, ilower, iupper, values); hypre_TFree(values); }
int hypre_BoxSetExtents( hypre_Box *box, hypre_Index imin, hypre_Index imax ) { int ierr = 0; hypre_CopyIndex(imin, hypre_BoxIMin(box)); hypre_CopyIndex(imax, hypre_BoxIMax(box)); return ierr; }
int hypre_SStructGraphFindBoxEndpt(hypre_SStructGraph *graph, int part, int var, int proc, int endpt, int boxi) { hypre_SStructGrid *grid = hypre_SStructGraphGrid(graph); int type = hypre_SStructGraphObjectType(graph); hypre_BoxMap *map; hypre_BoxMapEntry *map_entry; hypre_StructGrid *sgrid; hypre_Box *box; int rank; HYPRE_BigInt big_rank; map= hypre_SStructGridMap(grid, part, var); hypre_BoxMapFindBoxProcEntry(map, boxi, proc, &map_entry); sgrid= hypre_SStructPGridSGrid(hypre_SStructGridPGrid(grid, part), var); box = hypre_StructGridBox(sgrid, boxi); /* get the global rank of the endpt corner of box boxi */ if (endpt < 1) { hypre_SStructMapEntryGetGlobalRank(map_entry, hypre_BoxIMin(box), &big_rank, type); } else { hypre_SStructMapEntryGetGlobalRank(map_entry, hypre_BoxIMax(box), &big_rank, type); } if (type == HYPRE_SSTRUCT || type == HYPRE_STRUCT) { rank = (int)(big_rank - hypre_SStructGridGhstartRank(grid)); } if (type == HYPRE_PARCSR) { rank = (int)(big_rank - hypre_SStructGridStartRank(grid)); } return rank; }
int hypre_SStructPMatrixSetBoxValues( hypre_SStructPMatrix *pmatrix, hypre_Index ilower, hypre_Index iupper, int var, int nentries, int *entries, double *values, int add_to ) { hypre_SStructStencil *stencil = hypre_SStructPMatrixStencil(pmatrix, var); int *smap = hypre_SStructPMatrixSMap(pmatrix, var); int *vars = hypre_SStructStencilVars(stencil); hypre_StructMatrix *smatrix; hypre_Box *box; int *sentries; int i; smatrix = hypre_SStructPMatrixSMatrix(pmatrix, var, vars[entries[0]]); box = hypre_BoxCreate(); hypre_CopyIndex(ilower, hypre_BoxIMin(box)); hypre_CopyIndex(iupper, hypre_BoxIMax(box)); sentries = hypre_SStructPMatrixSEntries(pmatrix); for (i = 0; i < nentries; i++) { sentries[i] = smap[entries[i]]; } hypre_StructMatrixSetBoxValues(smatrix, box, nentries, sentries, values, add_to); hypre_BoxDestroy(box); return hypre_error_flag; }
int hypre_SStructUMatrixSetBoxValues( hypre_SStructMatrix *matrix, int part, hypre_Index ilower, hypre_Index iupper, int var, int nentries, int *entries, double *values, int add_to ) { HYPRE_IJMatrix ijmatrix = hypre_SStructMatrixIJMatrix(matrix); hypre_SStructGraph *graph = hypre_SStructMatrixGraph(matrix); hypre_SStructGrid *grid = hypre_SStructGraphGrid(graph); hypre_SStructStencil *stencil = hypre_SStructGraphStencil(graph, part, var); int *vars = hypre_SStructStencilVars(stencil); hypre_Index *shape = hypre_SStructStencilShape(stencil); int size = hypre_SStructStencilSize(stencil); hypre_IndexRef offset; hypre_BoxMap *map; hypre_BoxMapEntry **map_entries; int nmap_entries; hypre_BoxMapEntry **map_to_entries; int nmap_to_entries; int nrows; int *ncols; HYPRE_BigInt *rows; HYPRE_BigInt *cols; double *ijvalues; hypre_Box *box; hypre_Box *to_box; hypre_Box *map_box; hypre_Box *int_box; hypre_Index index; hypre_Index rs, cs; int sy, sz; HYPRE_BigInt row_base, col_base; int val_base; int e, entry, ii, jj, i, j, k; int proc, myproc; /* GEC1002 the matrix type */ int matrix_type = hypre_SStructMatrixObjectType(matrix); box = hypre_BoxCreate(); /*------------------------------------------ * all stencil entries *------------------------------------------*/ if (entries[0] < size) { to_box = hypre_BoxCreate(); map_box = hypre_BoxCreate(); int_box = hypre_BoxCreate(); hypre_CopyIndex(ilower, hypre_BoxIMin(box)); hypre_CopyIndex(iupper, hypre_BoxIMax(box)); /* ZTODO: check that this change fixes multiple-entry problem */ nrows = hypre_BoxVolume(box)*nentries; ncols = hypre_CTAlloc(int, nrows); for (i = 0; i < nrows; i++) { ncols[i] = 1; } rows = hypre_CTAlloc(HYPRE_BigInt, nrows); cols = hypre_CTAlloc(HYPRE_BigInt, nrows); ijvalues = hypre_CTAlloc(double, nrows); sy = (hypre_IndexX(iupper) - hypre_IndexX(ilower) + 1); sz = (hypre_IndexY(iupper) - hypre_IndexY(ilower) + 1) * sy; map = hypre_SStructGridMap(grid, part, var); hypre_BoxMapIntersect(map, ilower, iupper, &map_entries, &nmap_entries); for (ii = 0; ii < nmap_entries; ii++) { /* Only Set values if I am the owner process; off-process AddTo and Get * values are done by IJ */ if (!add_to) { hypre_SStructMapEntryGetProcess(map_entries[ii], &proc); MPI_Comm_rank(hypre_SStructGridComm(grid), &myproc); if (proc != myproc) { continue; } } /* GEC1002 introducing the strides based on the type of the matrix */ hypre_SStructMapEntryGetStrides(map_entries[ii], rs, matrix_type); hypre_CopyIndex(ilower, hypre_BoxIMin(box)); hypre_CopyIndex(iupper, hypre_BoxIMax(box)); hypre_BoxMapEntryGetExtents(map_entries[ii], hypre_BoxIMin(map_box), hypre_BoxIMax(map_box)); hypre_IntersectBoxes(box, map_box, int_box); hypre_CopyBox(int_box, box); nrows = 0; for (e = 0; e < nentries; e++) { entry = entries[e]; hypre_CopyBox(box, to_box); offset = shape[entry]; hypre_BoxIMinX(to_box) += hypre_IndexX(offset); hypre_BoxIMinY(to_box) += hypre_IndexY(offset); hypre_BoxIMinZ(to_box) += hypre_IndexZ(offset); hypre_BoxIMaxX(to_box) += hypre_IndexX(offset); hypre_BoxIMaxY(to_box) += hypre_IndexY(offset); hypre_BoxIMaxZ(to_box) += hypre_IndexZ(offset); map = hypre_SStructGridMap(grid, part, vars[entry]); hypre_BoxMapIntersect(map, hypre_BoxIMin(to_box), hypre_BoxIMax(to_box), &map_to_entries, &nmap_to_entries ); for (jj = 0; jj < nmap_to_entries; jj++) { /* GEC1002 introducing the strides based on the type of the matrix */ hypre_SStructMapEntryGetStrides(map_to_entries[jj], cs, matrix_type); hypre_BoxMapEntryGetExtents(map_to_entries[jj], hypre_BoxIMin(map_box), hypre_BoxIMax(map_box)); hypre_IntersectBoxes(to_box, map_box, int_box); hypre_CopyIndex(hypre_BoxIMin(int_box), index); /* GEC1002 introducing the rank based on the type of the matrix */ hypre_SStructMapEntryGetGlobalRank(map_to_entries[jj], index, &col_base,matrix_type); hypre_IndexX(index) -= hypre_IndexX(offset); hypre_IndexY(index) -= hypre_IndexY(offset); hypre_IndexZ(index) -= hypre_IndexZ(offset); /* GEC1002 introducing the rank based on the type of the matrix */ hypre_SStructMapEntryGetGlobalRank(map_entries[ii], index, &row_base,matrix_type); hypre_IndexX(index) -= hypre_IndexX(ilower); hypre_IndexY(index) -= hypre_IndexY(ilower); hypre_IndexZ(index) -= hypre_IndexZ(ilower); val_base = e + (hypre_IndexX(index) + hypre_IndexY(index)*sy + hypre_IndexZ(index)*sz) * nentries; for (k = 0; k < hypre_BoxSizeZ(int_box); k++) { for (j = 0; j < hypre_BoxSizeY(int_box); j++) { for (i = 0; i < hypre_BoxSizeX(int_box); i++) { rows[nrows] = row_base + (HYPRE_BigInt)(i*rs[0] + j*rs[1] + k*rs[2]); cols[nrows] = col_base + (HYPRE_BigInt)(i*cs[0] + j*cs[1] + k*cs[2]); ijvalues[nrows] = values[val_base + (i + j*sy + k*sz)*nentries]; nrows++; } } } } hypre_TFree(map_to_entries); } /*------------------------------------------ * set IJ values one stencil entry at a time *------------------------------------------*/ if (add_to > 0) { HYPRE_IJMatrixAddToValues(ijmatrix, nrows, ncols, (const HYPRE_BigInt *) rows, (const HYPRE_BigInt *) cols, (const double *) ijvalues); } else if (add_to > -1) { HYPRE_IJMatrixSetValues(ijmatrix, nrows, ncols, (const HYPRE_BigInt *) rows, (const HYPRE_BigInt *) cols, (const double *) ijvalues); } else { HYPRE_IJMatrixGetValues(ijmatrix, nrows, ncols, rows, cols, values); } } hypre_TFree(map_entries); hypre_TFree(ncols); hypre_TFree(rows); hypre_TFree(cols); hypre_TFree(ijvalues); hypre_BoxDestroy(to_box); hypre_BoxDestroy(map_box); hypre_BoxDestroy(int_box); }
/*-------------------------------------------------------------------------- * hypre_FacZeroCFSten: Zeroes the coarse stencil coefficients that reach * into an underlying coarsened refinement box. * Algo: For each cbox * { * 1) refine cbox and expand by one in each direction * 2) boxman_intersect with the fboxman * 3) loop over intersection boxes to see if stencil * reaches over. * } *--------------------------------------------------------------------------*/ HYPRE_Int hypre_FacZeroCFSten( hypre_SStructPMatrix *Af, hypre_SStructPMatrix *Ac, hypre_SStructGrid *grid, HYPRE_Int fine_part, hypre_Index rfactors ) { hypre_BoxManager *fboxman; hypre_BoxManEntry **boxman_entries; HYPRE_Int nboxman_entries; hypre_SStructPGrid *p_cgrid; hypre_Box fgrid_box; hypre_StructGrid *cgrid; hypre_BoxArray *cgrid_boxes; hypre_Box *cgrid_box; hypre_Box scaled_box; hypre_Box *shift_ibox; hypre_StructMatrix *smatrix; hypre_StructStencil *stencils; HYPRE_Int stencil_size; hypre_Index refine_factors, upper_shift; hypre_Index stride; hypre_Index stencil_shape; hypre_Index zero_index, ilower, iupper; HYPRE_Int nvars, var1, var2; HYPRE_Int ndim; hypre_Box *ac_dbox; HYPRE_Real *ac_ptr; hypre_Index loop_size; HYPRE_Int iac; HYPRE_Int ci, i, j; HYPRE_Int abs_shape; HYPRE_Int ierr = 0; p_cgrid = hypre_SStructPMatrixPGrid(Ac); nvars = hypre_SStructPMatrixNVars(Ac); ndim = hypre_SStructPGridNDim(p_cgrid); hypre_BoxInit(&fgrid_box, ndim); hypre_BoxInit(&scaled_box, ndim); hypre_ClearIndex(zero_index); hypre_ClearIndex(stride); hypre_ClearIndex(upper_shift); for (i= 0; i< ndim; i++) { stride[i]= 1; upper_shift[i]= rfactors[i]-1; } hypre_CopyIndex(rfactors, refine_factors); if (ndim < 3) { for (i= ndim; i< 3; i++) { refine_factors[i]= 1; } } for (var1= 0; var1< nvars; var1++) { cgrid= hypre_SStructPGridSGrid(hypre_SStructPMatrixPGrid(Ac), var1); cgrid_boxes= hypre_StructGridBoxes(cgrid); fboxman= hypre_SStructGridBoxManager(grid, fine_part, var1); /*------------------------------------------------------------------ * For each parent coarse box find all fboxes that may be connected * through a stencil entry- refine this box, expand it by one * in each direction, and boxman_intersect with fboxman *------------------------------------------------------------------*/ hypre_ForBoxI(ci, cgrid_boxes) { cgrid_box= hypre_BoxArrayBox(cgrid_boxes, ci); hypre_StructMapCoarseToFine(hypre_BoxIMin(cgrid_box), zero_index, refine_factors, hypre_BoxIMin(&scaled_box)); hypre_StructMapCoarseToFine(hypre_BoxIMax(cgrid_box), upper_shift, refine_factors, hypre_BoxIMax(&scaled_box)); hypre_SubtractIndexes(hypre_BoxIMin(&scaled_box), stride, 3, hypre_BoxIMin(&scaled_box)); hypre_AddIndexes(hypre_BoxIMax(&scaled_box), stride, 3, hypre_BoxIMax(&scaled_box)); hypre_BoxManIntersect(fboxman, hypre_BoxIMin(&scaled_box), hypre_BoxIMax(&scaled_box), &boxman_entries, &nboxman_entries); for (var2= 0; var2< nvars; var2++) { stencils= hypre_SStructPMatrixSStencil(Ac, var1, var2); if (stencils != NULL) { stencil_size= hypre_StructStencilSize(stencils); smatrix = hypre_SStructPMatrixSMatrix(Ac, var1, var2); ac_dbox = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(smatrix), ci); /*--------------------------------------------------------- * Find the stencil coefficients that must be zeroed off. * Loop over all possible boxes. *---------------------------------------------------------*/ for (i= 0; i< stencil_size; i++) { hypre_CopyIndex(hypre_StructStencilElement(stencils, i), stencil_shape); AbsStencilShape(stencil_shape, abs_shape); if (abs_shape) /* non-centre stencils are zeroed */ { /* look for connecting fboxes that must be zeroed. */ for (j= 0; j< nboxman_entries; j++) { hypre_BoxManEntryGetExtents(boxman_entries[j], ilower, iupper); hypre_BoxSetExtents(&fgrid_box, ilower, iupper); shift_ibox= hypre_CF_StenBox(&fgrid_box, cgrid_box, stencil_shape, refine_factors, ndim); if ( hypre_BoxVolume(shift_ibox) ) { ac_ptr= hypre_StructMatrixExtractPointerByIndex(smatrix, ci, stencil_shape); hypre_BoxGetSize(shift_ibox, loop_size); hypre_BoxLoop1Begin(ndim, loop_size, ac_dbox, hypre_BoxIMin(shift_ibox), stride, iac); #ifdef HYPRE_USING_OPENMP #pragma omp parallel for private(HYPRE_BOX_PRIVATE,iac) HYPRE_SMP_SCHEDULE #endif hypre_BoxLoop1For(iac) { ac_ptr[iac] = 0.0; } hypre_BoxLoop1End(iac); } /* if ( hypre_BoxVolume(shift_ibox) ) */ hypre_BoxDestroy(shift_ibox); } /* for (j= 0; j< nboxman_entries; j++) */ } /* if (abs_shape) */ } /* for (i= 0; i< stencil_size; i++) */ } /* if (stencils != NULL) */ } /* for (var2= 0; var2< nvars; var2++) */ hypre_TFree(boxman_entries); } /* hypre_ForBoxI ci */
HYPRE_Int hypre_CreateCommInfoFromStencil( hypre_StructGrid *grid, hypre_StructStencil *stencil, hypre_CommInfo **comm_info_ptr ) { HYPRE_Int i,j,k, d, m, s; hypre_BoxArrayArray *send_boxes; hypre_BoxArrayArray *recv_boxes; HYPRE_Int **send_procs; HYPRE_Int **recv_procs; HYPRE_Int **send_rboxnums; HYPRE_Int **recv_rboxnums; hypre_BoxArrayArray *send_rboxes; hypre_BoxArrayArray *recv_rboxes; hypre_BoxArray *local_boxes; HYPRE_Int num_boxes; HYPRE_Int *local_ids; hypre_BoxManager *boxman; hypre_Index *stencil_shape; hypre_IndexRef stencil_offset; hypre_IndexRef pshift; hypre_Box *box; hypre_Box *hood_box; hypre_Box *grow_box; hypre_Box *extend_box; hypre_Box *int_box; hypre_Box *periodic_box; HYPRE_Int stencil_grid[3][3][3]; HYPRE_Int grow[3][2]; hypre_BoxManEntry **entries; hypre_BoxManEntry *entry; HYPRE_Int num_entries; hypre_BoxArray *neighbor_boxes = NULL; HYPRE_Int *neighbor_procs = NULL; HYPRE_Int *neighbor_ids = NULL; HYPRE_Int *neighbor_shifts = NULL; HYPRE_Int neighbor_count; HYPRE_Int neighbor_alloc; hypre_Index ilower, iupper; hypre_BoxArray *send_box_array; hypre_BoxArray *recv_box_array; hypre_BoxArray *send_rbox_array; hypre_BoxArray *recv_rbox_array; hypre_Box **cboxes; hypre_Box *cboxes_mem; HYPRE_Int *cboxes_neighbor_location; HYPRE_Int num_cboxes, cbox_alloc; HYPRE_Int istart[3], istop[3]; HYPRE_Int sgindex[3]; HYPRE_Int num_periods, loc, box_id, id, proc_id; HYPRE_Int myid; MPI_Comm comm; /*------------------------------------------------------ * Initializations *------------------------------------------------------*/ local_boxes = hypre_StructGridBoxes(grid); local_ids = hypre_StructGridIDs(grid); num_boxes = hypre_BoxArraySize(local_boxes); num_periods = hypre_StructGridNumPeriods(grid); boxman = hypre_StructGridBoxMan(grid); comm = hypre_StructGridComm(grid); hypre_MPI_Comm_rank(comm, &myid); for (k = 0; k < 3; k++) { for (j = 0; j < 3; j++) { for (i = 0; i < 3; i++) { stencil_grid[i][j][k] = 0; } } } /*------------------------------------------------------ * Compute the "grow" information from the stencil *------------------------------------------------------*/ stencil_shape = hypre_StructStencilShape(stencil); for (d = 0; d < 3; d++) { grow[d][0] = 0; grow[d][1] = 0; } for (s = 0; s < hypre_StructStencilSize(stencil); s++) { stencil_offset = stencil_shape[s]; for (d = 0; d < 3; d++) { m = stencil_offset[d]; istart[d] = 1; istop[d] = 1; if (m < 0) { istart[d] = 0; grow[d][0] = hypre_max(grow[d][0], -m); } else if (m > 0) { istop[d] = 2; grow[d][1] = hypre_max(grow[d][1], m); } } /* update stencil grid from the grow_stencil */ for (k = istart[2]; k <= istop[2]; k++) { for (j = istart[1]; j <= istop[1]; j++) { for (i = istart[0]; i <= istop[0]; i++) { stencil_grid[i][j][k] = 1; } } } } /*------------------------------------------------------ * Compute send/recv boxes and procs for each local box *------------------------------------------------------*/ /* initialize: for each local box, we create an array of send/recv info */ send_boxes = hypre_BoxArrayArrayCreate(num_boxes); recv_boxes = hypre_BoxArrayArrayCreate(num_boxes); send_procs = hypre_CTAlloc(HYPRE_Int *, num_boxes); recv_procs = hypre_CTAlloc(HYPRE_Int *, num_boxes); /* Remote boxnums and boxes describe data on the opposing processor, so some shifting of boxes is needed below for periodic neighbor boxes. Remote box info is also needed for receives to allow for reverse communication. */ send_rboxnums = hypre_CTAlloc(HYPRE_Int *, num_boxes); send_rboxes = hypre_BoxArrayArrayCreate(num_boxes); recv_rboxnums = hypre_CTAlloc(HYPRE_Int *, num_boxes); recv_rboxes = hypre_BoxArrayArrayCreate(num_boxes); grow_box = hypre_BoxCreate(); extend_box = hypre_BoxCreate(); int_box = hypre_BoxCreate(); periodic_box = hypre_BoxCreate(); /* storage we will use and keep track of the neighbors */ neighbor_alloc = 30; /* initial guess at max size */ neighbor_boxes = hypre_BoxArrayCreate(neighbor_alloc); neighbor_procs = hypre_CTAlloc(HYPRE_Int, neighbor_alloc); neighbor_ids = hypre_CTAlloc(HYPRE_Int, neighbor_alloc); neighbor_shifts = hypre_CTAlloc(HYPRE_Int, neighbor_alloc); /* storage we will use to collect all of the intersected boxes (the send and recv regions for box i (this may not be enough in the case of periodic boxes, so we will have to check) */ cbox_alloc = hypre_BoxManNEntries(boxman); cboxes_neighbor_location = hypre_CTAlloc(HYPRE_Int, cbox_alloc); cboxes = hypre_CTAlloc(hypre_Box *, cbox_alloc); cboxes_mem = hypre_CTAlloc(hypre_Box, cbox_alloc); /******* loop through each local box **************/ for (i = 0; i < num_boxes; i++) { /* get the box */ box = hypre_BoxArrayBox(local_boxes, i); /* box_id = local_ids[i]; the box id in the Box Manager is the box number, * and we use this to find out if a box has intersected with itself */ box_id = i; /* grow box local i according to the stencil*/ hypre_CopyBox(box, grow_box); for (d = 0; d < 3; d++) { hypre_BoxIMinD(grow_box, d) -= grow[d][0]; hypre_BoxIMaxD(grow_box, d) += grow[d][1]; } /* extend_box - to find the list of potential neighbors, we need to grow the local box a bit differently in case, for example, the stencil grows in one dimension [0] and not the other [1] */ hypre_CopyBox(box, extend_box); for (d = 0; d < 3; d++) { hypre_BoxIMinD(extend_box, d) -= hypre_max(grow[d][0],grow[d][1]); hypre_BoxIMaxD(extend_box, d) += hypre_max(grow[d][0],grow[d][1]); } /*------------------------------------------------ * Determine the neighbors of box i *------------------------------------------------*/ /* Do this by intersecting the extend box with the BoxManager. We must also check for periodic neighbors. */ neighbor_count = 0; hypre_BoxArraySetSize(neighbor_boxes, 0); /* shift the box by each period (k=0 is original box) */ for (k = 0; k < num_periods; k++) { hypre_CopyBox(extend_box, periodic_box); pshift = hypre_StructGridPShift(grid, k); hypre_BoxShiftPos(periodic_box, pshift); /* get the intersections */ hypre_BoxManIntersect(boxman, hypre_BoxIMin(periodic_box) , hypre_BoxIMax(periodic_box) , &entries , &num_entries); /* note: do we need to remove the intersection with our original box? no if periodic, yes if non-periodic (k=0) */ /* unpack entries (first check storage) */ if (neighbor_count + num_entries > neighbor_alloc) { neighbor_alloc = neighbor_count + num_entries + 5; neighbor_procs = hypre_TReAlloc(neighbor_procs, HYPRE_Int, neighbor_alloc); neighbor_ids = hypre_TReAlloc(neighbor_ids, HYPRE_Int, neighbor_alloc); neighbor_shifts = hypre_TReAlloc(neighbor_shifts, HYPRE_Int, neighbor_alloc); } /* check storage for the array */ hypre_BoxArraySetSize(neighbor_boxes, neighbor_count + num_entries); /* now unpack */ for (j = 0; j < num_entries; j++) { entry = entries[j]; proc_id = hypre_BoxManEntryProc(entry); id = hypre_BoxManEntryId(entry); /* don't keep box i in the non-periodic case*/ if (!k) { if((myid == proc_id) && (box_id == id)) { continue; } } hypre_BoxManEntryGetExtents(entry, ilower, iupper); hypre_BoxSetExtents(hypre_BoxArrayBox(neighbor_boxes, neighbor_count), ilower, iupper); /* shift the periodic boxes (needs to be the opposite of above) */ if (k) { hypre_BoxShiftNeg( hypre_BoxArrayBox(neighbor_boxes, neighbor_count), pshift); } neighbor_procs[neighbor_count] = proc_id; neighbor_ids[neighbor_count] = id; neighbor_shifts[neighbor_count] = k; neighbor_count++; } hypre_BoxArraySetSize(neighbor_boxes, neighbor_count); hypre_TFree(entries); } /* end of loop through periods k */ /* Now we have a list of all of the neighbors for box i! */ /* note: we don't want/need to remove duplicates - they should have different intersections (TO DO: put more thought into if there are ever any exceptions to this? - the intersection routine already eliminates duplicates - so what i mean is eliminating duplicates from multiple intersection calls in periodic case) */ /*------------------------------------------------ * Compute recv_box_array for box i *------------------------------------------------*/ /* check size of storage for cboxes */ /* let's make sure that we have enough storage in case each neighbor produces a send/recv region */ if (neighbor_count > cbox_alloc) { cbox_alloc = neighbor_count; cboxes_neighbor_location = hypre_TReAlloc(cboxes_neighbor_location, HYPRE_Int, cbox_alloc); cboxes = hypre_TReAlloc(cboxes, hypre_Box *, cbox_alloc); cboxes_mem = hypre_TReAlloc(cboxes_mem, hypre_Box, cbox_alloc); } /* Loop through each neighbor box. If the neighbor box intersects the grown box i (grown according to our stencil), then the intersection is a recv region. If the neighbor box was shifted to handle periodicity, we need to (positive) shift it back. */ num_cboxes = 0; for (k = 0; k < neighbor_count; k++) { hood_box = hypre_BoxArrayBox(neighbor_boxes, k); /* check the stencil grid to see if it makes sense to intersect */ for (d = 0; d < 3; d++) { sgindex[d] = 1; s = hypre_BoxIMinD(hood_box, d) - hypre_BoxIMaxD(box, d); if (s > 0) { sgindex[d] = 2; } s = hypre_BoxIMinD(box, d) - hypre_BoxIMaxD(hood_box, d); if (s > 0) { sgindex[d] = 0; } } /* it makes sense only if we have at least one non-zero entry */ if (stencil_grid[sgindex[0]][sgindex[1]][sgindex[2]]) { /* intersect - result is int_box */ hypre_IntersectBoxes(grow_box, hood_box, int_box); /* if we have a positive volume box, this is a recv region */ if (hypre_BoxVolume(int_box)) { /* keep track of which neighbor: k... */ cboxes_neighbor_location[num_cboxes] = k; cboxes[num_cboxes] = &cboxes_mem[num_cboxes]; /* keep the intersected box */ hypre_CopyBox(int_box, cboxes[num_cboxes]); num_cboxes++; } } } /* end of loop through each neighbor */ /* create recv_box_array and recv_procs for box i */ recv_box_array = hypre_BoxArrayArrayBoxArray(recv_boxes, i); hypre_BoxArraySetSize(recv_box_array, num_cboxes); recv_procs[i] = hypre_CTAlloc(HYPRE_Int, num_cboxes); recv_rboxnums[i] = hypre_CTAlloc(HYPRE_Int, num_cboxes); recv_rbox_array = hypre_BoxArrayArrayBoxArray(recv_rboxes, i); hypre_BoxArraySetSize(recv_rbox_array, num_cboxes); for (m = 0; m < num_cboxes; m++) { loc = cboxes_neighbor_location[m]; recv_procs[i][m] = neighbor_procs[loc]; recv_rboxnums[i][m] = neighbor_ids[loc]; hypre_CopyBox(cboxes[m], hypre_BoxArrayBox(recv_box_array, m)); /* if periodic, positive shift before copying to the rbox_array */ if (neighbor_shifts[loc]) /* periodic if shift != 0 */ { pshift = hypre_StructGridPShift(grid, neighbor_shifts[loc]); hypre_BoxShiftPos(cboxes[m], pshift); } hypre_CopyBox(cboxes[m], hypre_BoxArrayBox(recv_rbox_array, m)); cboxes[m] = NULL; } /*------------------------------------------------ * Compute send_box_array for box i *------------------------------------------------*/ /* Loop through each neighbor box. If the grown neighbor box intersects box i, then the intersection is a send region. If the neighbor box was shifted to handle periodicity, we need to (positive) shift it back. */ num_cboxes = 0; for (k = 0; k < neighbor_count; k++) { hood_box = hypre_BoxArrayBox(neighbor_boxes, k); /* check the stencil grid to see if it makes sense to intersect */ for (d = 0; d < 3; d++) { sgindex[d] = 1; s = hypre_BoxIMinD(box, d) - hypre_BoxIMaxD(hood_box, d); if (s > 0) { sgindex[d] = 2; } s = hypre_BoxIMinD(hood_box, d) - hypre_BoxIMaxD(box, d); if (s > 0) { sgindex[d] = 0; } } /* it makes sense only if we have at least one non-zero entry */ if (stencil_grid[sgindex[0]][sgindex[1]][sgindex[2]]) { /* grow the neighbor box and intersect */ hypre_CopyBox(hood_box, grow_box); for (d = 0; d < 3; d++) { hypre_BoxIMinD(grow_box, d) -= grow[d][0]; hypre_BoxIMaxD(grow_box, d) += grow[d][1]; } hypre_IntersectBoxes(box, grow_box, int_box); /* if we have a positive volume box, this is a send region */ if (hypre_BoxVolume(int_box)) { /* keep track of which neighbor: k... */ cboxes_neighbor_location[num_cboxes] = k; cboxes[num_cboxes] = &cboxes_mem[num_cboxes]; /* keep the intersected box */ hypre_CopyBox(int_box, cboxes[num_cboxes]); num_cboxes++; } } }/* end of loop through neighbors */ /* create send_box_array and send_procs for box i */ send_box_array = hypre_BoxArrayArrayBoxArray(send_boxes, i); hypre_BoxArraySetSize(send_box_array, num_cboxes); send_procs[i] = hypre_CTAlloc(HYPRE_Int, num_cboxes); send_rboxnums[i] = hypre_CTAlloc(HYPRE_Int, num_cboxes); send_rbox_array = hypre_BoxArrayArrayBoxArray(send_rboxes, i); hypre_BoxArraySetSize(send_rbox_array, num_cboxes); for (m = 0; m < num_cboxes; m++) { loc = cboxes_neighbor_location[m]; send_procs[i][m] = neighbor_procs[loc]; send_rboxnums[i][m] = neighbor_ids[loc]; hypre_CopyBox(cboxes[m], hypre_BoxArrayBox(send_box_array, m)); /* if periodic, positive shift before copying to the rbox_array */ if (neighbor_shifts[loc]) /* periodic if shift != 0 */ { pshift = hypre_StructGridPShift(grid, neighbor_shifts[loc]); hypre_BoxShiftPos(cboxes[m], pshift); } hypre_CopyBox(cboxes[m], hypre_BoxArrayBox(send_rbox_array, m)); cboxes[m] = NULL; } } /* end of loop through each local box */
HYPRE_Int hypre_FacZeroCData( void *fac_vdata, hypre_SStructMatrix *A ) { hypre_FACData *fac_data = fac_vdata; hypre_SStructGrid *grid; hypre_SStructPGrid *p_cgrid; hypre_StructGrid *cgrid; hypre_BoxArray *cgrid_boxes; hypre_Box *cgrid_box; hypre_BoxManager *fboxman; hypre_BoxManEntry **boxman_entries; HYPRE_Int nboxman_entries; hypre_Box scaled_box; hypre_Box intersect_box; hypre_SStructPMatrix *level_pmatrix; hypre_StructStencil *stencils; HYPRE_Int stencil_size; hypre_Index *refine_factors; hypre_Index temp_index; hypre_Index ilower, iupper; HYPRE_Int max_level = fac_data -> max_levels; HYPRE_Int *level_to_part = fac_data -> level_to_part; HYPRE_Int ndim = hypre_SStructMatrixNDim(A); HYPRE_Int part_crse = 0; HYPRE_Int part_fine = 1; HYPRE_Int level; HYPRE_Int nvars, var; HYPRE_Int ci, i, j, rem, intersect_size; double *values; HYPRE_Int ierr = 0; for (level= max_level; level> 0; level--) { level_pmatrix = hypre_SStructMatrixPMatrix(fac_data -> A_level[level], part_crse); grid = (fac_data -> grid_level[level]); refine_factors= &(fac_data -> refine_factors[level]); p_cgrid= hypre_SStructGridPGrid(grid, part_crse); nvars = hypre_SStructPGridNVars(p_cgrid); for (var= 0; var< nvars; var++) { stencils = hypre_SStructPMatrixSStencil(level_pmatrix, var, var); stencil_size= hypre_StructStencilSize(stencils); /*--------------------------------------------------------------------- * For each variable, find the underlying boxes for each coarse box. *---------------------------------------------------------------------*/ cgrid = hypre_SStructPGridSGrid(p_cgrid, var); cgrid_boxes = hypre_StructGridBoxes(cgrid); fboxman = hypre_SStructGridBoxManager(grid, part_fine, var); hypre_ForBoxI(ci, cgrid_boxes) { cgrid_box= hypre_BoxArrayBox(cgrid_boxes, ci); hypre_ClearIndex(temp_index); hypre_StructMapCoarseToFine(hypre_BoxIMin(cgrid_box), temp_index, *refine_factors, hypre_BoxIMin(&scaled_box)); for (i= 0; i< ndim; i++) { temp_index[i]= (*refine_factors)[i]-1; } hypre_StructMapCoarseToFine(hypre_BoxIMax(cgrid_box), temp_index, *refine_factors, hypre_BoxIMax(&scaled_box)); hypre_BoxManIntersect(fboxman, hypre_BoxIMin(&scaled_box), hypre_BoxIMax(&scaled_box), &boxman_entries, &nboxman_entries); for (i= 0; i< nboxman_entries; i++) { hypre_BoxManEntryGetExtents(boxman_entries[i], ilower, iupper); hypre_BoxSetExtents(&intersect_box, ilower, iupper); hypre_IntersectBoxes(&intersect_box, &scaled_box, &intersect_box); /* adjust the box so that it is divisible by refine_factors */ for (j= 0; j< ndim; j++) { rem= hypre_BoxIMin(&intersect_box)[j]%(*refine_factors)[j]; if (rem) { hypre_BoxIMin(&intersect_box)[j]+=(*refine_factors)[j] - rem; } } hypre_ClearIndex(temp_index); hypre_StructMapFineToCoarse(hypre_BoxIMin(&intersect_box), temp_index, *refine_factors, hypre_BoxIMin(&intersect_box)); hypre_StructMapFineToCoarse(hypre_BoxIMax(&intersect_box), temp_index, *refine_factors, hypre_BoxIMax(&intersect_box)); intersect_size= hypre_BoxVolume(&intersect_box); if (intersect_size > 0) { /*------------------------------------------------------------ * Coarse underlying box found. Now zero off. *------------------------------------------------------------*/ values= hypre_CTAlloc(double, intersect_size); for (j= 0; j< stencil_size; j++) { HYPRE_SStructMatrixSetBoxValues(fac_data -> A_level[level], part_crse, hypre_BoxIMin(&intersect_box), hypre_BoxIMax(&intersect_box), var, 1, &j, values); HYPRE_SStructMatrixSetBoxValues(A, level_to_part[level-1], hypre_BoxIMin(&intersect_box), hypre_BoxIMax(&intersect_box), var, 1, &j, values); } hypre_TFree(values); } /* if (intersect_size > 0) */ } /* for (i= 0; i< nboxman_entries; i++) */ hypre_TFree(boxman_entries); } /* hypre_ForBoxI(ci, cgrid_boxes) */ } /* for (var= 0; var< nvars; var++) */
HYPRE_Int hypre_AMR_CFCoarsen( hypre_SStructMatrix * A, hypre_SStructMatrix * fac_A, hypre_Index refine_factors, HYPRE_Int level ) { MPI_Comm comm = hypre_SStructMatrixComm(A); hypre_SStructGraph *graph = hypre_SStructMatrixGraph(A); HYPRE_Int graph_type = hypre_SStructGraphObjectType(graph); hypre_SStructGrid *grid = hypre_SStructGraphGrid(graph); HYPRE_Int nUventries = hypre_SStructGraphNUVEntries(graph); HYPRE_IJMatrix ij_A = hypre_SStructMatrixIJMatrix(A); HYPRE_Int matrix_type= hypre_SStructMatrixObjectType(A); HYPRE_Int ndim = hypre_SStructMatrixNDim(A); hypre_SStructPMatrix *A_pmatrix; hypre_StructMatrix *smatrix_var; hypre_StructStencil *stencils; HYPRE_Int stencil_size; hypre_Index stencil_shape_i; hypre_Index loop_size; hypre_Box refined_box; double **a_ptrs; hypre_Box *A_dbox; HYPRE_Int part_crse= level-1; HYPRE_Int part_fine= level; hypre_BoxManager *fboxman; hypre_BoxManEntry **boxman_entries, *boxman_entry; HYPRE_Int nboxman_entries; hypre_Box boxman_entry_box; hypre_BoxArrayArray ***fgrid_cinterface_extents; hypre_StructGrid *cgrid; hypre_BoxArray *cgrid_boxes; hypre_Box *cgrid_box; hypre_Index node_extents; hypre_Index stridec, stridef; hypre_BoxArrayArray *cinterface_arrays; hypre_BoxArray *cinterface_array; hypre_Box *fgrid_cinterface; HYPRE_Int centre; HYPRE_Int ci, fi, boxi; HYPRE_Int max_stencil_size= 27; HYPRE_Int false= 0; HYPRE_Int true = 1; HYPRE_Int found; HYPRE_Int *stencil_ranks, *rank_stencils; HYPRE_Int rank, startrank; double *vals; HYPRE_Int i, j, iA; HYPRE_Int nvars, var1; hypre_Index lindex, zero_index; hypre_Index index1, index2; hypre_Index index_temp; hypre_SStructUVEntry *Uventry; HYPRE_Int nUentries, cnt1; HYPRE_Int box_array_size; HYPRE_Int *ncols, *rows, *cols; HYPRE_Int *temp1, *temp2; HYPRE_Int myid; hypre_MPI_Comm_rank(comm, &myid); hypre_SetIndex(zero_index, 0, 0, 0); /*-------------------------------------------------------------------------- * Task: Coarsen the CF interface connections of A into fac_A so that * fac_A will have the stencil coefficients extending into a coarsened * fbox. The centre coefficient is constructed to preserve the row sum. *--------------------------------------------------------------------------*/ if (graph_type == HYPRE_SSTRUCT) { startrank = hypre_SStructGridGhstartRank(grid); } if (graph_type == HYPRE_PARCSR) { startrank = hypre_SStructGridStartRank(grid); } /*-------------------------------------------------------------------------- * Fine grid strides by the refinement factors. *--------------------------------------------------------------------------*/ hypre_SetIndex(stridec, 1, 1, 1); for (i= 0; i< ndim; i++) { stridef[i]= refine_factors[i]; } for (i= ndim; i< 3; i++) { stridef[i]= 1; } /*-------------------------------------------------------------------------- * Determine the c/f interface index boxes: fgrid_cinterface_extents. * These are between fpart= level and cpart= (level-1). The * fgrid_cinterface_extents are indexed by cboxes, but fboxes that * abutt a given cbox must be considered. Moreover, for each fbox, * we can have a c/f interface from a number of different stencil * directions- i.e., we have a boxarrayarray for each cbox, each * fbox leading to a boxarray. * * Algo.: For each cbox: * 1) refine & stretch by a unit in each dimension. * 2) boxman_intersect with the fgrid boxman to get all fboxes contained * or abutting this cbox. * 3) get the fgrid_cinterface_extents for each of these fboxes. * * fgrid_cinterface_extents[var1][ci] *--------------------------------------------------------------------------*/ A_pmatrix= hypre_SStructMatrixPMatrix(fac_A, part_crse); nvars = hypre_SStructPMatrixNVars(A_pmatrix); fgrid_cinterface_extents= hypre_TAlloc(hypre_BoxArrayArray **, nvars); for (var1= 0; var1< nvars; var1++) { fboxman= hypre_SStructGridBoxManager(grid, part_fine, var1); stencils= hypre_SStructPMatrixSStencil(A_pmatrix, var1, var1); cgrid= hypre_SStructPGridSGrid(hypre_SStructPMatrixPGrid(A_pmatrix), var1); cgrid_boxes= hypre_StructGridBoxes(cgrid); fgrid_cinterface_extents[var1]= hypre_TAlloc(hypre_BoxArrayArray *, hypre_BoxArraySize(cgrid_boxes)); hypre_ForBoxI(ci, cgrid_boxes) { cgrid_box= hypre_BoxArrayBox(cgrid_boxes, ci); hypre_StructMapCoarseToFine(hypre_BoxIMin(cgrid_box), zero_index, refine_factors, hypre_BoxIMin(&refined_box)); hypre_SetIndex(index1, refine_factors[0]-1, refine_factors[1]-1, refine_factors[2]-1); hypre_StructMapCoarseToFine(hypre_BoxIMax(cgrid_box), index1, refine_factors, hypre_BoxIMax(&refined_box)); /*------------------------------------------------------------------------ * Stretch the refined_box so that a BoxManIntersect will get abutting * fboxes. *------------------------------------------------------------------------*/ for (i= 0; i< ndim; i++) { hypre_BoxIMin(&refined_box)[i]-= 1; hypre_BoxIMax(&refined_box)[i]+= 1; } hypre_BoxManIntersect(fboxman, hypre_BoxIMin(&refined_box), hypre_BoxIMax(&refined_box), &boxman_entries, &nboxman_entries); fgrid_cinterface_extents[var1][ci]= hypre_BoxArrayArrayCreate(nboxman_entries); /*------------------------------------------------------------------------ * Get the fgrid_cinterface_extents using var1-var1 stencil (only like- * variables couple). *------------------------------------------------------------------------*/ if (stencils != NULL) { for (i= 0; i< nboxman_entries; i++) { hypre_BoxManEntryGetExtents(boxman_entries[i], hypre_BoxIMin(&boxman_entry_box), hypre_BoxIMax(&boxman_entry_box)); hypre_CFInterfaceExtents2(&boxman_entry_box, cgrid_box, stencils, refine_factors, hypre_BoxArrayArrayBoxArray(fgrid_cinterface_extents[var1][ci], i) ); } } hypre_TFree(boxman_entries); } /* hypre_ForBoxI(ci, cgrid_boxes) */ } /* for (var1= 0; var1< nvars; var1++) */
/*-------------------------------------------------------------------------- * hypre_Maxwell_Grad.c * Forms a node-to-edge gradient operator. Looping over the * edge grid so that each processor fills up only its own rows. Each * processor will have its processor interface nodal ranks. * Loops over two types of boxes, interior of grid boxes and boundary * of boxes. Algo: * find all nodal and edge physical boundary points and set * the appropriate flag to be 0 at a boundary dof. * set -1's in value array * for each edge box, * for interior * { * connect edge ijk (row) to nodes (col) connected to this edge * and change -1 to 1 if needed; * } * for boundary layers * { * if edge not on the physical boundary connect only the nodes * that are not on the physical boundary * } * set parcsr matrix with values; * * Note that the nodes that are on the processor interface can be * on the physical boundary. But the off-proc edges connected to this * type of node will be a physical boundary edge. * *--------------------------------------------------------------------------*/ hypre_ParCSRMatrix * hypre_Maxwell_Grad(hypre_SStructGrid *grid) { MPI_Comm comm = (grid -> comm); HYPRE_IJMatrix T_grad; hypre_ParCSRMatrix *parcsr_grad; HYPRE_Int matrix_type= HYPRE_PARCSR; hypre_SStructGrid *node_grid, *edge_grid; hypre_SStructPGrid *pgrid; hypre_StructGrid *var_grid; hypre_BoxArray *boxes, *tmp_box_array1, *tmp_box_array2; hypre_BoxArray *node_boxes, *edge_boxes, *cell_boxes; hypre_Box *box, *cell_box; hypre_Box layer, interior_box; hypre_Box *box_piece; hypre_BoxManager *boxman; hypre_BoxManEntry *entry; HYPRE_Int *inode, *jedge; HYPRE_Int nrows, nnodes, *nflag, *eflag, *ncols; HYPRE_Real *vals; hypre_Index index; hypre_Index loop_size, start, lindex; hypre_Index shift, shift2; hypre_Index *offsets, *varoffsets; HYPRE_Int nparts= hypre_SStructGridNParts(grid); HYPRE_Int ndim = hypre_SStructGridNDim(grid); HYPRE_SStructVariable vartype_node, *vartype_edges; HYPRE_SStructVariable *vartypes; HYPRE_Int nvars, part; HYPRE_Int i, j, k, m, n, d; HYPRE_Int *direction, ndirection; HYPRE_Int ilower, iupper; HYPRE_Int jlower, jupper; HYPRE_Int start_rank1, start_rank2, rank; HYPRE_Int myproc; HYPRE_Int ierr=0; hypre_BoxInit(&layer, ndim); hypre_BoxInit(&interior_box, ndim); hypre_MPI_Comm_rank(comm, &myproc); hypre_ClearIndex(shift); for (i= 0; i< ndim; i++) { hypre_IndexD(shift, i)= -1; } /* To get the correct ranks, separate node & edge grids must be formed. Note that the edge vars must be ordered the same way as is in grid.*/ HYPRE_SStructGridCreate(comm, ndim, nparts, &node_grid); HYPRE_SStructGridCreate(comm, ndim, nparts, &edge_grid); vartype_node = HYPRE_SSTRUCT_VARIABLE_NODE; vartype_edges= hypre_TAlloc(HYPRE_SStructVariable, ndim); /* Assuming the same edge variable types on all parts */ pgrid = hypre_SStructGridPGrid(grid, 0); vartypes= hypre_SStructPGridVarTypes(pgrid); nvars = hypre_SStructPGridNVars(pgrid); k= 0; for (i= 0; i< nvars; i++) { j= vartypes[i]; switch(j) { case 2: { vartype_edges[k]= HYPRE_SSTRUCT_VARIABLE_XFACE; k++; break; } case 3: { vartype_edges[k]= HYPRE_SSTRUCT_VARIABLE_YFACE; k++; break; } case 5: { vartype_edges[k]= HYPRE_SSTRUCT_VARIABLE_XEDGE; k++; break; } case 6: { vartype_edges[k]= HYPRE_SSTRUCT_VARIABLE_YEDGE; k++; break; } case 7: { vartype_edges[k]= HYPRE_SSTRUCT_VARIABLE_ZEDGE; k++; break; } } /* switch(j) */ } /* for (i= 0; i< nvars; i++) */ for (part= 0; part< nparts; part++) { pgrid= hypre_SStructGridPGrid(grid, part); var_grid= hypre_SStructPGridCellSGrid(pgrid) ; boxes= hypre_StructGridBoxes(var_grid); hypre_ForBoxI(j, boxes) { box= hypre_BoxArrayBox(boxes, j); HYPRE_SStructGridSetExtents(node_grid, part, hypre_BoxIMin(box), hypre_BoxIMax(box)); HYPRE_SStructGridSetExtents(edge_grid, part, hypre_BoxIMin(box), hypre_BoxIMax(box)); } HYPRE_SStructGridSetVariables(node_grid, part, 1, &vartype_node); HYPRE_SStructGridSetVariables(edge_grid, part, ndim, vartype_edges); }
box = hypre_BoxArrayBox(boxes, 0); hypre_SStructBoxManEntryGetGlobalCSRank(entry, hypre_BoxIMin(box), &jlower); /* upper rank */ part= nparts-1; pgrid = hypre_SStructGridPGrid(edge_grid, part); nvars = hypre_SStructPGridNVars(pgrid); var_grid= hypre_SStructPGridSGrid(pgrid, nvars-1); boxes = hypre_StructGridBoxes(var_grid); box = hypre_BoxArrayBox(boxes, hypre_BoxArraySize(boxes)-1); hypre_SStructGridBoxProcFindBoxManEntry(edge_grid, part, nvars-1, hypre_BoxArraySize(boxes)-1, myproc, &entry); hypre_SStructBoxManEntryGetGlobalCSRank(entry, hypre_BoxIMax(box), &iupper); pgrid = hypre_SStructGridPGrid(node_grid, part); nvars = hypre_SStructPGridNVars(pgrid); var_grid= hypre_SStructPGridSGrid(pgrid, nvars-1); boxes = hypre_StructGridBoxes(var_grid); box = hypre_BoxArrayBox(boxes, hypre_BoxArraySize(boxes)-1); hypre_SStructGridBoxProcFindBoxManEntry(node_grid, part, nvars-1, hypre_BoxArraySize(boxes)-1, myproc, &entry); hypre_SStructBoxManEntryGetGlobalCSRank(entry, hypre_BoxIMax(box), &jupper); HYPRE_IJMatrixCreate(comm, ilower, iupper, jlower, jupper, &T_grad); HYPRE_IJMatrixSetObjectType(T_grad, HYPRE_PARCSR); HYPRE_IJMatrixInitialize(T_grad);
HYPRE_Int hypre_GeneralBoxBoundaryIntersect( hypre_Box *box, hypre_StructGrid *grid, hypre_Index stencil_element, hypre_BoxArray *boundary ) { hypre_BoxManager *boxman; hypre_BoxManEntry **entries; hypre_BoxArray *int_boxes, *tmp_boxes; hypre_Box *bbox, *ibox; HYPRE_Int nentries, i, j; HYPRE_Int *dd; HYPRE_Int ndim; ndim = hypre_StructGridNDim(grid); dd = hypre_CTAlloc(HYPRE_Int, ndim); for (i=0; i < ndim; i++) dd[i] = hypre_IndexD(stencil_element, i); /* set bbox to the box surface of interest */ hypre_BoxArraySetSize(boundary, 1); bbox = hypre_BoxArrayBox(boundary, 0); hypre_CopyBox(box, bbox); /* temporarily shift bbox in direction dir and intersect with the grid */ for (i=0; i < ndim; i++) { hypre_BoxIMinD(bbox, i) += dd[i]; hypre_BoxIMaxD(bbox, i) += dd[i]; } boxman = hypre_StructGridBoxMan(grid); hypre_BoxManIntersect(boxman, hypre_BoxIMin(bbox), hypre_BoxIMax(bbox), &entries, &nentries); for (i=0; i < ndim; i++) { hypre_BoxIMinD(bbox, i) -= dd[i]; hypre_BoxIMaxD(bbox, i) -= dd[i]; } /* shift intersected boxes in direction -dir and subtract from bbox */ int_boxes = hypre_BoxArrayCreate(nentries, ndim); tmp_boxes = hypre_BoxArrayCreate(0, ndim); for (i = 0; i < nentries; i++) { ibox = hypre_BoxArrayBox(int_boxes, i); hypre_BoxManEntryGetExtents( entries[i], hypre_BoxIMin(ibox), hypre_BoxIMax(ibox)); for (j=0; j < ndim; j++) { hypre_BoxIMinD(ibox, j) -= dd[j]; hypre_BoxIMaxD(ibox, j) -= dd[j]; } } hypre_SubtractBoxArrays(boundary, int_boxes, tmp_boxes); hypre_BoxArrayDestroy(int_boxes); hypre_BoxArrayDestroy(tmp_boxes); hypre_TFree(entries); hypre_TFree(dd); return hypre_error_flag; }
HYPRE_Int hypre_StructInterpAssemble( hypre_StructMatrix *A, hypre_StructMatrix *P, HYPRE_Int P_stored_as_transpose, HYPRE_Int cdir, hypre_Index index, hypre_Index stride ) { hypre_StructGrid *grid = hypre_StructMatrixGrid(A); hypre_BoxArrayArray *box_aa; hypre_BoxArray *box_a; hypre_Box *box; hypre_CommInfo *comm_info; hypre_CommPkg *comm_pkg; hypre_CommHandle *comm_handle; HYPRE_Int num_ghost[] = {0, 0, 0, 0, 0, 0}; HYPRE_Int i, j, s, dim; if (hypre_StructMatrixConstantCoefficient(P) != 0) { return hypre_error_flag; } /* set num_ghost */ dim = hypre_StructGridDim(grid); for (j = 0; j < dim; j++) { num_ghost[2*j] = 1; num_ghost[2*j+1] = 1; } if (P_stored_as_transpose) { num_ghost[2*cdir] = 2; num_ghost[2*cdir+1] = 2; } /* comm_info <-- From fine grid grown by num_ghost */ hypre_CreateCommInfoFromNumGhost(grid, num_ghost, &comm_info); /* Project and map comm_info onto coarsened index space */ hypre_CommInfoProjectSend(comm_info, index, stride); hypre_CommInfoProjectRecv(comm_info, index, stride); for (s = 0; s < 3; s++) { switch(s) { case 0: box_aa = hypre_CommInfoSendBoxes(comm_info); hypre_SetIndex(hypre_CommInfoSendStride(comm_info), 1, 1, 1); break; case 1: box_aa = hypre_CommInfoRecvBoxes(comm_info); hypre_SetIndex(hypre_CommInfoRecvStride(comm_info), 1, 1, 1); break; case 2: box_aa = hypre_CommInfoSendRBoxes(comm_info); break; } hypre_ForBoxArrayI(j, box_aa) { box_a = hypre_BoxArrayArrayBoxArray(box_aa, j); hypre_ForBoxI(i, box_a) { box = hypre_BoxArrayBox(box_a, i); hypre_StructMapFineToCoarse(hypre_BoxIMin(box), index, stride, hypre_BoxIMin(box)); hypre_StructMapFineToCoarse(hypre_BoxIMax(box), index, stride, hypre_BoxIMax(box)); } }
/*-------------------------------------------------------------------------- * 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; }
/*-------------------------------------------------------------------------- * hypre_CFInterfaceExtents: Given a cgrid_box, a fgrid_box, and stencils, * find the extents of the C/F interface (interface nodes in the C box). * Boxes corresponding to stencil shifts are stored in the first stencil_size * boxes, and the union of these are appended to the end of the returned * box_array. *--------------------------------------------------------------------------*/ hypre_BoxArray * hypre_CFInterfaceExtents( hypre_Box *fgrid_box, hypre_Box *cgrid_box, hypre_StructStencil *stencils, hypre_Index rfactors ) { hypre_BoxArray *stencil_box_extents; hypre_BoxArray *union_boxes; hypre_Box *cfine_box; hypre_Box *box; hypre_Index stencil_shape, cstart, zero_index, neg_index; HYPRE_Int stencil_size; HYPRE_Int abs_stencil; HYPRE_Int ndim= hypre_StructStencilDim(stencils); HYPRE_Int i, j; hypre_ClearIndex(zero_index); hypre_ClearIndex(neg_index); for (i= 0; i< ndim; i++) { neg_index[i]= -1; } hypre_CopyIndex(hypre_BoxIMin(cgrid_box), cstart); stencil_size = hypre_StructStencilSize(stencils); stencil_box_extents= hypre_BoxArrayCreate(stencil_size); union_boxes = hypre_BoxArrayCreate(0); for (i= 0; i< stencil_size; i++) { hypre_CopyIndex(hypre_StructStencilElement(stencils, i), stencil_shape); AbsStencilShape(stencil_shape, abs_stencil); if (abs_stencil) /* only do if not the centre stencil */ { cfine_box= hypre_CF_StenBox(fgrid_box, cgrid_box, stencil_shape, rfactors, ndim); if ( hypre_BoxVolume(cfine_box) ) { hypre_AppendBox(cfine_box, union_boxes); hypre_CopyBox(cfine_box, hypre_BoxArrayBox(stencil_box_extents, i)); for (j= 0; j< ndim; j++) { hypre_BoxIMin(cfine_box)[j]-= cstart[j]; hypre_BoxIMax(cfine_box)[j]-= cstart[j]; } hypre_CopyBox(cfine_box, hypre_BoxArrayBox(stencil_box_extents, i)); } else { hypre_BoxSetExtents(hypre_BoxArrayBox(stencil_box_extents, i), zero_index, neg_index); } hypre_BoxDestroy(cfine_box); } else /* centre */ { hypre_BoxSetExtents(hypre_BoxArrayBox(stencil_box_extents, i), zero_index, neg_index); } } /*-------------------------------------------------------------------------- * Union the stencil_box_extents to get the full CF extents and append to * the end of the stencil_box_extents BoxArray. Then shift the unioned boxes * by cstart. *--------------------------------------------------------------------------*/ if (hypre_BoxArraySize(union_boxes) > 1) { hypre_UnionBoxes(union_boxes); } hypre_ForBoxI(i, union_boxes) { hypre_AppendBox(hypre_BoxArrayBox(union_boxes, i), stencil_box_extents); }
HYPRE_Int hypre_FacSemiRestrictSetup2( void *fac_restrict_vdata, hypre_SStructVector *r, HYPRE_Int part_crse, HYPRE_Int part_fine, hypre_SStructPVector *rc, hypre_Index rfactors ) { HYPRE_Int ierr = 0; hypre_FacSemiRestrictData2 *fac_restrict_data = fac_restrict_vdata; MPI_Comm comm= hypre_SStructPVectorComm(rc); hypre_CommInfo *comm_info; hypre_CommPkg **interlevel_comm; hypre_SStructPVector *rf= hypre_SStructVectorPVector(r, part_fine); hypre_StructVector *s_rc, *s_cvector; hypre_SStructPGrid *pgrid; hypre_SStructPVector *fgrid_cvectors; hypre_SStructPGrid *fgrid_coarsen; hypre_BoxArrayArray **identity_arrayboxes; hypre_BoxArrayArray **fullwgt_ownboxes; hypre_BoxArrayArray **fullwgt_sendboxes; hypre_BoxArray *boxarray; hypre_BoxArray *tmp_boxarray, *intersect_boxes; HYPRE_Int ***own_cboxnums; hypre_BoxArrayArray **send_boxes, *send_rboxes; HYPRE_Int ***send_processes; HYPRE_Int ***send_remote_boxnums; hypre_BoxArrayArray **recv_boxes, *recv_rboxes; HYPRE_Int ***recv_processes; HYPRE_Int ***recv_remote_boxnums; hypre_BoxManager *boxman; hypre_BoxManEntry **boxman_entries; HYPRE_Int nboxman_entries; hypre_Box box, scaled_box; hypre_Index zero_index, index, ilower, iupper; HYPRE_Int ndim= hypre_SStructVectorNDim(r); HYPRE_Int myproc, proc; HYPRE_Int nvars, vars; HYPRE_Int num_values; HYPRE_Int i, cnt1, cnt2; HYPRE_Int fi, ci; hypre_MPI_Comm_rank(comm, &myproc); hypre_ClearIndex(zero_index); nvars= hypre_SStructPVectorNVars(rc); (fac_restrict_data -> nvars)= nvars; hypre_CopyIndex(rfactors, (fac_restrict_data -> stride)); for (i= ndim; i< 3; i++) { rfactors[i]= 1; } /* work vector for storing the fullweighted fgrid boxes */ hypre_SStructPGridCreate(hypre_SStructPVectorComm(rf), ndim, &fgrid_coarsen); pgrid= hypre_SStructPVectorPGrid(rf); for (vars= 0; vars< nvars; vars++) { boxarray= hypre_StructGridBoxes(hypre_SStructPGridSGrid(pgrid, vars)); hypre_ForBoxI(fi, boxarray) { hypre_CopyBox(hypre_BoxArrayBox(boxarray, fi), &box); hypre_StructMapFineToCoarse(hypre_BoxIMin(&box), zero_index, rfactors, hypre_BoxIMin(&box)); hypre_StructMapFineToCoarse(hypre_BoxIMax(&box), zero_index, rfactors, hypre_BoxIMax(&box)); hypre_SStructPGridSetExtents(fgrid_coarsen, hypre_BoxIMin(&box), hypre_BoxIMax(&box)); } }
/*-------------------------------------------------------------------------- * hypre_SStructSharedDOF_ParcsrMatRowsComm * Given a sstruct_grid & parcsr matrix with rows corresponding to the * sstruct_grid, determine and extract the rows that must be communicated. * These rows are for shared dof that geometrically lie on processor * boundaries but internally are stored on one processor. * Algo: * for each cellbox * RECVs: * i) stretch the cellbox to the variable box * ii) in the appropriate (dof-dependent) direction, take the * boundary and boxman_intersect to extract boxmanentries * that contain these boundary edges. * iii)loop over the boxmanentries and see if they belong * on this proc or another proc * a) if belong on another proc, these are the recvs: * count and prepare the communication buffers and * values. * * SENDs: * i) form layer of cells that is one layer off cellbox * (stretches in the appropriate direction) * ii) boxman_intersect with the cellgrid boxman * iii)loop over the boxmanentries and see if they belong * on this proc or another proc * a) if belong on another proc, these are the sends: * count and prepare the communication buffers and * values. * * Note: For the recv data, the dof can come from only one processor. * For the send data, the dof can go to more than one processor * (the same dof is on the boundary of several cells). *--------------------------------------------------------------------------*/ HYPRE_Int hypre_SStructSharedDOF_ParcsrMatRowsComm( hypre_SStructGrid *grid, hypre_ParCSRMatrix *A, HYPRE_Int *num_offprocrows_ptr, hypre_MaxwellOffProcRow ***OffProcRows_ptr) { MPI_Comm A_comm= hypre_ParCSRMatrixComm(A); MPI_Comm grid_comm= hypre_SStructGridComm(grid); HYPRE_Int matrix_type= HYPRE_PARCSR; HYPRE_Int nparts= hypre_SStructGridNParts(grid); HYPRE_Int ndim = hypre_SStructGridNDim(grid); hypre_SStructGrid *cell_ssgrid; hypre_SStructPGrid *pgrid; hypre_StructGrid *cellgrid; hypre_BoxArray *cellboxes; hypre_Box *box, *cellbox, vbox, boxman_entry_box; hypre_Index loop_size, start; HYPRE_Int loopi, loopj, loopk; HYPRE_Int start_rank, end_rank, rank; HYPRE_Int i, j, k, m, n, t, part, var, nvars; HYPRE_SStructVariable *vartypes; HYPRE_Int nbdry_slabs; hypre_BoxArray *recv_slabs, *send_slabs; hypre_Index varoffset; hypre_BoxManager **boxmans, *cell_boxman; hypre_BoxManEntry **boxman_entries, *entry; HYPRE_Int nboxman_entries; hypre_Index ishift, jshift, kshift, zero_index; hypre_Index ilower, iupper, index; HYPRE_Int proc, nprocs, myproc; HYPRE_Int *SendToProcs, *RecvFromProcs; HYPRE_Int **send_RowsNcols; /* buffer for rows & ncols */ HYPRE_Int *send_RowsNcols_alloc; HYPRE_Int *send_ColsData_alloc; HYPRE_Int *tot_nsendRowsNcols, *tot_sendColsData; double **vals; /* buffer for cols & data */ HYPRE_Int *col_inds; double *values; hypre_MPI_Request *requests; hypre_MPI_Status *status; HYPRE_Int **rbuffer_RowsNcols; double **rbuffer_ColsData; HYPRE_Int num_sends, num_recvs; hypre_MaxwellOffProcRow **OffProcRows; HYPRE_Int *starts; HYPRE_Int ierr= 0; hypre_MPI_Comm_rank(A_comm, &myproc); hypre_MPI_Comm_size(grid_comm, &nprocs); start_rank= hypre_ParCSRMatrixFirstRowIndex(A); end_rank = hypre_ParCSRMatrixLastRowIndex(A); hypre_SetIndex(ishift, 1, 0, 0); hypre_SetIndex(jshift, 0, 1, 0); hypre_SetIndex(kshift, 0, 0, 1); hypre_SetIndex(zero_index, 0, 0, 0); /* need a cellgrid boxman to determine the send boxes -> only the cell dofs are unique so a boxman intersect can be used to get the edges that must be sent. */ HYPRE_SStructGridCreate(grid_comm, ndim, nparts, &cell_ssgrid); vartypes= hypre_CTAlloc(HYPRE_SStructVariable, 1); vartypes[0]= HYPRE_SSTRUCT_VARIABLE_CELL; for (i= 0; i< nparts; i++) { pgrid= hypre_SStructGridPGrid(grid, i); cellgrid= hypre_SStructPGridCellSGrid(pgrid); cellboxes= hypre_StructGridBoxes(cellgrid); hypre_ForBoxI(j, cellboxes) { box= hypre_BoxArrayBox(cellboxes, j); HYPRE_SStructGridSetExtents(cell_ssgrid, i, hypre_BoxIMin(box), hypre_BoxIMax(box)); } HYPRE_SStructGridSetVariables(cell_ssgrid, i, 1, vartypes); }
hypre_SStructSendInfoData * hypre_SStructSendInfo( hypre_StructGrid *fgrid, hypre_BoxManager *cboxman, hypre_Index rfactor ) { hypre_SStructSendInfoData *sendinfo_data; MPI_Comm comm= hypre_SStructVectorComm(fgrid); hypre_BoxArray *grid_boxes; hypre_Box *grid_box, cbox; hypre_Box *intersect_box, boxman_entry_box; hypre_BoxManEntry **boxman_entries; HYPRE_Int nboxman_entries; hypre_BoxArrayArray *send_boxes; HYPRE_Int **send_processes; HYPRE_Int **send_remote_boxnums; hypre_Index ilower, iupper, index; HYPRE_Int myproc, proc; HYPRE_Int cnt; HYPRE_Int i, j; hypre_ClearIndex(index); hypre_MPI_Comm_rank(comm, &myproc); sendinfo_data= hypre_CTAlloc(hypre_SStructSendInfoData, 1); /*------------------------------------------------------------------------ * Create the structured sendbox patterns. * * send_boxes are obtained by intersecting this proc's fgrid boxes * with cgrid's box_man. Intersecting BoxManEntries not on this proc * will give boxes that we will need to send data to- i.e., we scan * through the boxes of grid and find the processors that own a chunk * of it. *------------------------------------------------------------------------*/ intersect_box = hypre_CTAlloc(hypre_Box, 1); grid_boxes = hypre_StructGridBoxes(fgrid); send_boxes= hypre_BoxArrayArrayCreate(hypre_BoxArraySize(grid_boxes)); send_processes= hypre_CTAlloc(HYPRE_Int *, hypre_BoxArraySize(grid_boxes)); send_remote_boxnums= hypre_CTAlloc(HYPRE_Int *, hypre_BoxArraySize(grid_boxes)); hypre_ForBoxI(i, grid_boxes) { grid_box= hypre_BoxArrayBox(grid_boxes, i); /*--------------------------------------------------------------------- * Find the boxarray that must be sent. BoxManIntersect returns * the full extents of the boxes that intersect with the given box. * We further need to intersect each box in the list with the given * box to determine the actual box that needs to be sent. *---------------------------------------------------------------------*/ hypre_SStructIndexScaleF_C(hypre_BoxIMin(grid_box), index, rfactor, hypre_BoxIMin(&cbox)); hypre_SStructIndexScaleF_C(hypre_BoxIMax(grid_box), index, rfactor, hypre_BoxIMax(&cbox)); hypre_BoxManIntersect(cboxman, hypre_BoxIMin(&cbox), hypre_BoxIMax(&cbox), &boxman_entries, &nboxman_entries); cnt= 0; for (j= 0; j< nboxman_entries; j++) { hypre_SStructBoxManEntryGetProcess(boxman_entries[j], &proc); if (proc != myproc) { cnt++; } } send_processes[i] = hypre_CTAlloc(HYPRE_Int, cnt); send_remote_boxnums[i]= hypre_CTAlloc(HYPRE_Int, cnt); cnt= 0; for (j= 0; j< nboxman_entries; j++) { hypre_SStructBoxManEntryGetProcess(boxman_entries[j], &proc); /* determine the chunk of the boxman_entries[j] box that is needed */ hypre_BoxManEntryGetExtents(boxman_entries[j], ilower, iupper); hypre_BoxSetExtents(&boxman_entry_box, ilower, iupper); hypre_IntersectBoxes(&boxman_entry_box, &cbox, &boxman_entry_box); if (proc != myproc) { send_processes[i][cnt] = proc; hypre_SStructBoxManEntryGetBoxnum(boxman_entries[j], &send_remote_boxnums[i][cnt]); hypre_AppendBox(&boxman_entry_box, hypre_BoxArrayArrayBoxArray(send_boxes, i)); cnt++; } } hypre_TFree(boxman_entries); } /* hypre_ForBoxI(i, grid_boxes) */
HYPRE_Int hypre_Maxwell_PhysBdy( hypre_SStructGrid **grid_l, HYPRE_Int num_levels, hypre_Index rfactors, HYPRE_Int ***BdryRanksl_ptr, HYPRE_Int **BdryRanksCntsl_ptr ) { MPI_Comm comm= (grid_l[0]-> comm); HYPRE_Int **BdryRanks_l; HYPRE_Int *BdryRanksCnts_l; HYPRE_Int *npts; HYPRE_Int *ranks, *upper_rank, *lower_rank; hypre_BoxManEntry *boxman_entry; hypre_SStructGrid *grid; hypre_SStructPGrid *pgrid; hypre_StructGrid *cell_fgrid, *cell_cgrid, *sgrid; hypre_BoxArrayArray ****bdry; hypre_BoxArrayArray *fbdry; hypre_BoxArrayArray *cbdry; hypre_BoxArray *box_array; hypre_BoxArray *fboxes, *cboxes; hypre_Box *fbox, *cbox; hypre_Box *box, *contract_fbox, rbox; hypre_Box intersect; HYPRE_Int **cbox_mapping, **fbox_mapping; HYPRE_Int **boxes_with_bdry; HYPRE_Int ndim, nvars; HYPRE_Int nboxes, nfboxes; HYPRE_Int boxi; hypre_Index zero_shift, upper_shift, lower_shift; hypre_Index loop_size, start, index, lindex; HYPRE_Int i, j, k, l, m, n, p; HYPRE_Int d; HYPRE_Int cnt; HYPRE_Int part= 0; /* NOTE, ASSUMING ONE PART */ HYPRE_Int matrix_type= HYPRE_PARCSR; HYPRE_Int myproc; HYPRE_Int ierr= 0; hypre_MPI_Comm_rank(comm, &myproc); ndim= hypre_SStructGridNDim(grid_l[0]); hypre_SetIndex3(zero_shift, 0, 0, 0); hypre_BoxInit(&intersect, ndim); /* bounding global ranks of this processor & allocate boundary box markers. */ upper_rank= hypre_CTAlloc(HYPRE_Int, num_levels); lower_rank= hypre_CTAlloc(HYPRE_Int, num_levels); boxes_with_bdry= hypre_TAlloc(HYPRE_Int *, num_levels); for (i= 0; i< num_levels; i++) { grid = grid_l[i]; lower_rank[i]= hypre_SStructGridStartRank(grid); /* note we are assuming only one part */ pgrid= hypre_SStructGridPGrid(grid, part); nvars= hypre_SStructPGridNVars(pgrid); sgrid= hypre_SStructPGridSGrid(pgrid, nvars-1); box_array= hypre_StructGridBoxes(sgrid); box = hypre_BoxArrayBox(box_array, hypre_BoxArraySize(box_array)-1); hypre_SStructGridBoxProcFindBoxManEntry(grid, part, nvars-1, hypre_BoxArraySize(box_array)-1, myproc, &boxman_entry); hypre_SStructBoxManEntryGetGlobalCSRank(boxman_entry, hypre_BoxIMax(box), &upper_rank[i]); sgrid= hypre_SStructPGridCellSGrid(pgrid); box_array= hypre_StructGridBoxes(sgrid); boxes_with_bdry[i]= hypre_CTAlloc(HYPRE_Int, hypre_BoxArraySize(box_array)); } /*----------------------------------------------------------------------------- * construct box_number mapping between levels, and offset strides because of * projection coarsening. Note: from the way the coarse boxes are created and * numbered, to determine the coarse box that matches the fbox, we need to * only check the tail end of the list of cboxes. In fact, given fbox_i, * if it's coarsened extents do not interesect with the first coarse box of the * tail end, then this fbox vanishes in the coarsening. * c/fbox_mapping gives the fine/coarse box mapping between two consecutive levels * of the multilevel hierarchy. *-----------------------------------------------------------------------------*/ if (num_levels > 1) { cbox_mapping= hypre_CTAlloc(HYPRE_Int *, num_levels); fbox_mapping= hypre_CTAlloc(HYPRE_Int *, num_levels); }