hypre_ForBoxI(i, boxes) { cbox_array = hypre_BoxArrayArrayBoxArray(dept_boxes, i); hypre_BoxArraySetSize(cbox_array, 1); cbox = hypre_BoxArrayBox(cbox_array, 0); hypre_CopyBox(hypre_BoxArrayBox(boxes, i), cbox); }
hypre_Box * hypre_BoxDuplicate( hypre_Box *box ) { hypre_Box *new_box; new_box = hypre_BoxCreate(); hypre_CopyBox(box, new_box); return new_box; }
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_BoxArray * hypre_BoxArrayDuplicate( hypre_BoxArray *box_array ) { hypre_BoxArray *new_box_array; int i; new_box_array = hypre_BoxArrayCreate(hypre_BoxArraySize(box_array)); hypre_ForBoxI(i, box_array) { hypre_CopyBox(hypre_BoxArrayBox(box_array, i), hypre_BoxArrayBox(new_box_array, i)); }
int hypre_SMGAxpy( double alpha, hypre_StructVector *x, hypre_StructVector *y, hypre_Index base_index, hypre_Index base_stride ) { int ierr = 0; hypre_Box *x_data_box; hypre_Box *y_data_box; int xi; int yi; double *xp; double *yp; hypre_BoxArray *boxes; hypre_Box *box; hypre_Index loop_size; hypre_IndexRef start; int i; int loopi, loopj, loopk; box = hypre_BoxCreate(); boxes = hypre_StructGridBoxes(hypre_StructVectorGrid(y)); hypre_ForBoxI(i, boxes) { hypre_CopyBox(hypre_BoxArrayBox(boxes, i), box); hypre_ProjectBox(box, base_index, base_stride); start = hypre_BoxIMin(box); x_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(x), i); y_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(y), i); xp = hypre_StructVectorBoxData(x, i); yp = hypre_StructVectorBoxData(y, i); hypre_BoxGetStrideSize(box, base_stride, loop_size); hypre_BoxLoop2Begin(loop_size, x_data_box, start, base_stride, xi, y_data_box, start, base_stride, yi); #define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,xi,yi #include "hypre_box_smp_forloop.h" hypre_BoxLoop2For(loopi, loopj, loopk, xi, yi) { yp[yi] += alpha * xp[xi]; }
hypre_BoxArray * hypre_GrowBoxByStencil( hypre_Box *box, hypre_StructStencil *stencil, int transpose ) { hypre_BoxArray *grow_box_array; hypre_BoxArray *shift_box_array; hypre_Box *shift_box; hypre_Index *stencil_shape; int s, d; stencil_shape = hypre_StructStencilShape(stencil); shift_box_array = hypre_BoxArrayCreate(hypre_StructStencilSize(stencil)); shift_box = hypre_BoxCreate(); for (s = 0; s < hypre_StructStencilSize(stencil); s++) { if (transpose) for (d = 0; d < 3; d++) { hypre_BoxIMinD(shift_box, d) = hypre_BoxIMinD(box, d) - hypre_IndexD(stencil_shape[s], d); hypre_BoxIMaxD(shift_box, d) = hypre_BoxIMaxD(box, d) - hypre_IndexD(stencil_shape[s], d); } else for (d = 0; d < 3; d++) { hypre_BoxIMinD(shift_box, d) = hypre_BoxIMinD(box, d) + hypre_IndexD(stencil_shape[s], d); hypre_BoxIMaxD(shift_box, d) = hypre_BoxIMaxD(box, d) + hypre_IndexD(stencil_shape[s], d); } hypre_CopyBox(shift_box, hypre_BoxArrayBox(shift_box_array, s)); } hypre_BoxDestroy(shift_box); hypre_UnionBoxes(shift_box_array); grow_box_array = shift_box_array; return grow_box_array; }
int hypre_StructVectorInitializeShell( hypre_StructVector *vector ) { int ierr = 0; hypre_StructGrid *grid; int *num_ghost; hypre_BoxArray *data_space; hypre_BoxArray *boxes; hypre_Box *box; hypre_Box *data_box; int *data_indices; int data_size; int i, d; /*----------------------------------------------------------------------- * Set up data_space *-----------------------------------------------------------------------*/ grid = hypre_StructVectorGrid(vector); if (hypre_StructVectorDataSpace(vector) == NULL) { num_ghost = hypre_StructVectorNumGhost(vector); boxes = hypre_StructGridBoxes(grid); data_space = hypre_BoxArrayCreate(hypre_BoxArraySize(boxes)); hypre_ForBoxI(i, boxes) { box = hypre_BoxArrayBox(boxes, i); data_box = hypre_BoxArrayBox(data_space, i); hypre_CopyBox(box, data_box); for (d = 0; d < 3; d++) { hypre_BoxIMinD(data_box, d) -= num_ghost[2*d]; hypre_BoxIMaxD(data_box, d) += num_ghost[2*d + 1]; } }
hypre_ForBoxI(i, boxes) { cbox_array = hypre_BoxArrayArrayBoxArray(indt_boxes, i); hypre_BoxArraySetSize(cbox_array, 1); cbox = hypre_BoxArrayBox(cbox_array, 0); hypre_CopyBox(hypre_BoxArrayBox(boxes, i), cbox); for (d = 0; d < 3; d++) { if ( (border[d][0]) ) { hypre_BoxIMinD(cbox, d) += border[d][0]; } if ( (border[d][1]) ) { hypre_BoxIMaxD(cbox, d) -= border[d][1]; } } }
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)); } }
int hypre_PointRelaxSetup( void *relax_vdata, hypre_StructMatrix *A, hypre_StructVector *b, hypre_StructVector *x ) { hypre_PointRelaxData *relax_data = (hypre_PointRelaxData *)relax_vdata; int num_pointsets = (relax_data -> num_pointsets); int *pointset_sizes = (relax_data -> pointset_sizes); hypre_Index *pointset_strides = (relax_data -> pointset_strides); hypre_Index **pointset_indices = (relax_data -> pointset_indices); hypre_StructVector *t; int diag_rank; hypre_ComputePkg **compute_pkgs; hypre_Index unit_stride; hypre_Index diag_index; hypre_IndexRef stride; hypre_IndexRef index; 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_BoxArrayArray *orig_indt_boxes; hypre_BoxArrayArray *orig_dept_boxes; hypre_BoxArrayArray *box_aa; hypre_BoxArray *box_a; hypre_Box *box; int box_aa_size; int box_a_size; hypre_BoxArrayArray *new_box_aa; hypre_BoxArray *new_box_a; hypre_Box *new_box; double scale; int frac; int i, j, k, p, m, compute_i; int ierr = 0; /*---------------------------------------------------------- * Set up the temp vector *----------------------------------------------------------*/ if ((relax_data -> t) == NULL) { t = hypre_StructVectorCreate(hypre_StructVectorComm(b), hypre_StructVectorGrid(b)); hypre_StructVectorSetNumGhost(t, hypre_StructVectorNumGhost(b)); hypre_StructVectorInitialize(t); hypre_StructVectorAssemble(t); (relax_data -> t) = t; } /*---------------------------------------------------------- * Find the matrix diagonal *----------------------------------------------------------*/ grid = hypre_StructMatrixGrid(A); stencil = hypre_StructMatrixStencil(A); hypre_SetIndex(diag_index, 0, 0, 0); diag_rank = hypre_StructStencilElementRank(stencil, diag_index); /*---------------------------------------------------------- * Set up the compute packages *----------------------------------------------------------*/ hypre_SetIndex(unit_stride, 1, 1, 1); compute_pkgs = hypre_CTAlloc(hypre_ComputePkg *, num_pointsets); for (p = 0; p < num_pointsets; p++) { hypre_CreateComputeInfo(grid, stencil, &send_boxes, &recv_boxes, &send_processes, &recv_processes, &orig_indt_boxes, &orig_dept_boxes); stride = pointset_strides[p]; for (compute_i = 0; compute_i < 2; compute_i++) { switch(compute_i) { case 0: box_aa = orig_indt_boxes; break; case 1: box_aa = orig_dept_boxes; break; } box_aa_size = hypre_BoxArrayArraySize(box_aa); new_box_aa = hypre_BoxArrayArrayCreate(box_aa_size); for (i = 0; i < box_aa_size; i++) { box_a = hypre_BoxArrayArrayBoxArray(box_aa, i); box_a_size = hypre_BoxArraySize(box_a); new_box_a = hypre_BoxArrayArrayBoxArray(new_box_aa, i); hypre_BoxArraySetSize(new_box_a, box_a_size * pointset_sizes[p]); k = 0; for (m = 0; m < pointset_sizes[p]; m++) { index = pointset_indices[p][m]; for (j = 0; j < box_a_size; j++) { box = hypre_BoxArrayBox(box_a, j); new_box = hypre_BoxArrayBox(new_box_a, k); hypre_CopyBox(box, new_box); hypre_ProjectBox(new_box, index, stride); k++; } } } switch(compute_i) { case 0: indt_boxes = new_box_aa; break; case 1: dept_boxes = new_box_aa; break; } } hypre_ComputePkgCreate(send_boxes, recv_boxes, unit_stride, unit_stride, send_processes, recv_processes, indt_boxes, dept_boxes, stride, grid, hypre_StructVectorDataSpace(x), 1, &compute_pkgs[p]); hypre_BoxArrayArrayDestroy(orig_indt_boxes); hypre_BoxArrayArrayDestroy(orig_dept_boxes); } /*---------------------------------------------------------- * Set up the relax data structure *----------------------------------------------------------*/ (relax_data -> A) = hypre_StructMatrixRef(A); (relax_data -> x) = hypre_StructVectorRef(x); (relax_data -> b) = hypre_StructVectorRef(b); (relax_data -> diag_rank) = diag_rank; (relax_data -> compute_pkgs) = compute_pkgs; /*----------------------------------------------------- * Compute flops *-----------------------------------------------------*/ scale = 0.0; for (p = 0; p < num_pointsets; p++) { stride = pointset_strides[p]; frac = hypre_IndexX(stride); frac *= hypre_IndexY(stride); frac *= hypre_IndexZ(stride); scale += (pointset_sizes[p] / frac); } (relax_data -> flops) = scale * (hypre_StructMatrixGlobalSize(A) + hypre_StructVectorGlobalSize(x)); return ierr; }
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); }
int hypre_SStructUMatrixInitialize( hypre_SStructMatrix *matrix ) { HYPRE_IJMatrix ijmatrix = hypre_SStructMatrixIJMatrix(matrix); hypre_SStructGraph *graph = hypre_SStructMatrixGraph(matrix); hypre_SStructGrid *grid = hypre_SStructGraphGrid(graph); int nparts = hypre_SStructGraphNParts(graph); hypre_SStructPGrid **pgrids = hypre_SStructGraphPGrids(graph); hypre_SStructStencil ***stencils = hypre_SStructGraphStencils(graph); int nUventries = hypre_SStructGraphNUVEntries(graph); int *iUventries = hypre_SStructGraphIUVEntries(graph); hypre_SStructUVEntry **Uventries = hypre_SStructGraphUVEntries(graph); int **nvneighbors = hypre_SStructGridNVNeighbors(grid); hypre_StructGrid *sgrid; hypre_SStructStencil *stencil; int *split; int nvars; int nrows, nnzs ; int part, var, entry, i, j, k,m,b; int *row_sizes; int max_row_size; int matrix_type = hypre_SStructMatrixObjectType(matrix); hypre_Box *gridbox; hypre_Box *loopbox; hypre_Box *ghostbox; hypre_BoxArray *boxes; int *num_ghost; HYPRE_IJMatrixSetObjectType(ijmatrix, HYPRE_PARCSR); /* GEC1002 the ghlocalsize is used to set the number of rows */ if (matrix_type == HYPRE_PARCSR) { nrows = hypre_SStructGridLocalSize(grid); } if (matrix_type == HYPRE_SSTRUCT || matrix_type == HYPRE_STRUCT) { nrows = hypre_SStructGridGhlocalSize(grid) ; } /* set row sizes */ m = 0; row_sizes = hypre_CTAlloc(int, nrows); max_row_size = 0; for (part = 0; part < nparts; part++) { nvars = hypre_SStructPGridNVars(pgrids[part]); for (var = 0; var < nvars; var++) { sgrid = hypre_SStructPGridSGrid(pgrids[part], var); stencil = stencils[part][var]; split = hypre_SStructMatrixSplit(matrix, part, var); nnzs = 0; for (entry = 0; entry < hypre_SStructStencilSize(stencil); entry++) { if (split[entry] == -1) { nnzs++; } } #if 0 /* TODO: For now, assume stencil is full/complete */ if (hypre_SStructMatrixSymmetric(matrix)) { nnzs = 2*nnzs - 1; } #endif /**************/ boxes = hypre_StructGridBoxes(sgrid) ; num_ghost = hypre_StructGridNumGhost(sgrid); for (b = 0; b < hypre_BoxArraySize(boxes); b++) { gridbox = hypre_BoxArrayBox(boxes, b); ghostbox = hypre_BoxCreate(); loopbox = hypre_BoxCreate(); hypre_CopyBox(gridbox,ghostbox); hypre_BoxExpand(ghostbox,num_ghost); if (matrix_type == HYPRE_SSTRUCT || matrix_type == HYPRE_STRUCT) { hypre_CopyBox(ghostbox,loopbox); } if (matrix_type == HYPRE_PARCSR) { hypre_CopyBox(gridbox,loopbox); } for (k = hypre_BoxIMinZ(loopbox); k <= hypre_BoxIMaxZ(loopbox); k++) { for (j = hypre_BoxIMinY(loopbox); j <= hypre_BoxIMaxY(loopbox); j++) { for (i = hypre_BoxIMinX(loopbox); i <= hypre_BoxIMaxX(loopbox); i++) { if ( ( ( i>=hypre_BoxIMinX(gridbox) ) && ( j>=hypre_BoxIMinY(gridbox) ) ) && ( k>=hypre_BoxIMinZ(gridbox) ) ) { if ( ( ( i<=hypre_BoxIMaxX(gridbox) ) && ( j<=hypre_BoxIMaxY(gridbox) ) ) && ( k<=hypre_BoxIMaxZ(gridbox) ) ) { row_sizes[m] = nnzs; max_row_size = hypre_max(max_row_size, row_sizes[m]); } } m++; } } } hypre_BoxDestroy(ghostbox); hypre_BoxDestroy(loopbox); } if (nvneighbors[part][var]) { max_row_size = hypre_max(max_row_size, hypre_SStructStencilSize(stencil)); } /*********************/ } } /* GEC0902 essentially for each UVentry we figure out how many extra columns * we need to add to the rowsizes */ for (entry = 0; entry < nUventries; entry++) { i = iUventries[entry]; row_sizes[i] += hypre_SStructUVEntryNUEntries(Uventries[i]); max_row_size = hypre_max(max_row_size, row_sizes[i]); } /* ZTODO: Update row_sizes based on neighbor off-part couplings */ HYPRE_IJMatrixSetRowSizes (ijmatrix, (const int *) row_sizes); hypre_TFree(row_sizes); hypre_SStructMatrixTmpColCoords(matrix) = hypre_CTAlloc(HYPRE_BigInt, max_row_size); hypre_SStructMatrixTmpCoeffs(matrix) = hypre_CTAlloc(double, max_row_size); /* GEC1002 at this point the processor has the partitioning (creation of ij) */ HYPRE_IJMatrixInitialize(ijmatrix); return hypre_error_flag; }
int hypre_StructMatrixInitializeShell( hypre_StructMatrix *matrix ) { int ierr = 0; hypre_StructGrid *grid; hypre_StructStencil *user_stencil; hypre_StructStencil *stencil; hypre_Index *stencil_shape; int stencil_size; int num_values; int *symm_elements; int *num_ghost; int extra_ghost[] = {0, 0, 0, 0, 0, 0}; hypre_BoxArray *data_space; hypre_BoxArray *boxes; hypre_Box *box; hypre_Box *data_box; int **data_indices; int data_size; int data_box_volume; int i, j, d; grid = hypre_StructMatrixGrid(matrix); /*----------------------------------------------------------------------- * Set up stencil and num_values: * The stencil is a "symmetrized" version of the user's stencil * as computed by hypre_StructStencilSymmetrize. * * The `symm_elements' array is used to determine what data is * explicitely stored (symm_elements[i] < 0) and what data does is * not explicitely stored (symm_elements[i] >= 0), but is instead * stored as the transpose coefficient at a neighboring grid point. *-----------------------------------------------------------------------*/ if (hypre_StructMatrixStencil(matrix) == NULL) { user_stencil = hypre_StructMatrixUserStencil(matrix); hypre_StructStencilSymmetrize(user_stencil, &stencil, &symm_elements); stencil_shape = hypre_StructStencilShape(stencil); stencil_size = hypre_StructStencilSize(stencil); if (!hypre_StructMatrixSymmetric(matrix)) { /* store all element data */ for (i = 0; i < stencil_size; i++) symm_elements[i] = -1; num_values = stencil_size; } else { num_values = (stencil_size + 1) / 2; } hypre_StructMatrixStencil(matrix) = stencil; hypre_StructMatrixSymmElements(matrix) = symm_elements; hypre_StructMatrixNumValues(matrix) = num_values; } /*----------------------------------------------------------------------- * Set ghost-layer size for symmetric storage * - All stencil coeffs are to be available at each point in the * grid, as well as in the user-specified ghost layer. *-----------------------------------------------------------------------*/ num_ghost = hypre_StructMatrixNumGhost(matrix); stencil = hypre_StructMatrixStencil(matrix); stencil_shape = hypre_StructStencilShape(stencil); stencil_size = hypre_StructStencilSize(stencil); symm_elements = hypre_StructMatrixSymmElements(matrix); for (i = 0; i < stencil_size; i++) { if (symm_elements[i] >= 0) { for (d = 0; d < 3; d++) { extra_ghost[2*d] = hypre_max(extra_ghost[2*d], -hypre_IndexD(stencil_shape[i], d)); extra_ghost[2*d + 1] = hypre_max(extra_ghost[2*d + 1], hypre_IndexD(stencil_shape[i], d)); } } } for (d = 0; d < 3; d++) { num_ghost[2*d] += extra_ghost[2*d]; num_ghost[2*d + 1] += extra_ghost[2*d + 1]; } /*----------------------------------------------------------------------- * Set up data_space *-----------------------------------------------------------------------*/ if (hypre_StructMatrixDataSpace(matrix) == NULL) { boxes = hypre_StructGridBoxes(grid); data_space = hypre_BoxArrayCreate(hypre_BoxArraySize(boxes)); hypre_ForBoxI(i, boxes) { box = hypre_BoxArrayBox(boxes, i); data_box = hypre_BoxArrayBox(data_space, i); hypre_CopyBox(box, data_box); for (d = 0; d < 3; d++) { hypre_BoxIMinD(data_box, d) -= num_ghost[2*d]; hypre_BoxIMaxD(data_box, d) += num_ghost[2*d + 1]; } }
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_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_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_SubtractBoxes( hypre_Box *box1, hypre_Box *box2, hypre_BoxArray *box_array ) { int ierr = 0; hypre_Box *box; hypre_Box *rembox; int d, size; /*------------------------------------------------------ * Set the box array size to the maximum possible, * plus one, to have space for the remainder box. *------------------------------------------------------*/ size = hypre_BoxArraySize(box_array); hypre_BoxArraySetSize(box_array, (size + 7)); /*------------------------------------------------------ * Subtract the boxes by cutting box1 in x, y, then z *------------------------------------------------------*/ rembox = hypre_BoxArrayBox(box_array, (size + 6)); hypre_CopyBox(box1, rembox); for (d = 0; d < 3; d++) { /* if the boxes do not intersect, the subtraction is trivial */ if ( (hypre_BoxIMinD(box2, d) > hypre_BoxIMaxD(rembox, d)) || (hypre_BoxIMaxD(box2, d) < hypre_BoxIMinD(rembox, d)) ) { size = hypre_BoxArraySize(box_array) - 7; hypre_CopyBox(box1, hypre_BoxArrayBox(box_array, size)); size++; break; } /* update the box array */ else { if ( hypre_BoxIMinD(box2, d) > hypre_BoxIMinD(rembox, d) ) { box = hypre_BoxArrayBox(box_array, size); hypre_CopyBox(rembox, box); hypre_BoxIMaxD(box, d) = hypre_BoxIMinD(box2, d) - 1; hypre_BoxIMinD(rembox, d) = hypre_BoxIMinD(box2, d); if ( hypre_BoxVolume(box)>0 ) size++; } if ( hypre_BoxIMaxD(box2, d) < hypre_BoxIMaxD(rembox, d) ) { box = hypre_BoxArrayBox(box_array, size); hypre_CopyBox(rembox, box); hypre_BoxIMinD(box, d) = hypre_BoxIMaxD(box2, d) + 1; hypre_BoxIMaxD(rembox, d) = hypre_BoxIMaxD(box2, d); if ( hypre_BoxVolume(box)>0 ) size++; } } } hypre_BoxArraySetSize(box_array, size); return ierr; }
/*-------------------------------------------------------------------------- * 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); }
int hypre_CreateComputeInfo( hypre_StructGrid *grid, hypre_StructStencil *stencil, hypre_ComputeInfo **compute_info_ptr ) { int ierr = 0; hypre_CommInfo *comm_info; hypre_BoxArrayArray *indt_boxes; hypre_BoxArrayArray *dept_boxes; hypre_BoxArray *boxes; hypre_BoxArray *cbox_array; hypre_Box *cbox; int i; #ifdef HYPRE_OVERLAP_COMM_COMP hypre_Box *rembox; hypre_Index *stencil_shape; int border[3][2] = {{0, 0}, {0, 0}, {0, 0}}; int cbox_array_size; int s, d; #endif /*------------------------------------------------------ * Extract needed grid info *------------------------------------------------------*/ boxes = hypre_StructGridBoxes(grid); /*------------------------------------------------------ * Get communication info *------------------------------------------------------*/ hypre_CreateCommInfoFromStencil(grid, stencil, &comm_info); #ifdef HYPRE_OVERLAP_COMM_COMP /*------------------------------------------------------ * Compute border info *------------------------------------------------------*/ stencil_shape = hypre_StructStencilShape(stencil); for (s = 0; s < hypre_StructStencilSize(stencil); s++) { for (d = 0; d < 3; d++) { i = hypre_IndexD(stencil_shape[s], d); if (i < 0) { border[d][0] = hypre_max(border[d][0], -i); } else if (i > 0) { border[d][1] = hypre_max(border[d][1], i); } } } /*------------------------------------------------------ * Set up the dependent boxes *------------------------------------------------------*/ dept_boxes = hypre_BoxArrayArrayCreate(hypre_BoxArraySize(boxes)); rembox = hypre_BoxCreate(); hypre_ForBoxI(i, boxes) { cbox_array = hypre_BoxArrayArrayBoxArray(dept_boxes, i); hypre_BoxArraySetSize(cbox_array, 6); hypre_CopyBox(hypre_BoxArrayBox(boxes, i), rembox); cbox_array_size = 0; for (d = 0; d < 3; d++) { if ( (hypre_BoxVolume(rembox)) && (border[d][0]) ) { cbox = hypre_BoxArrayBox(cbox_array, cbox_array_size); hypre_CopyBox(rembox, cbox); hypre_BoxIMaxD(cbox, d) = hypre_BoxIMinD(cbox, d) + border[d][0] - 1; hypre_BoxIMinD(rembox, d) = hypre_BoxIMinD(cbox, d) + border[d][0]; cbox_array_size++; } if ( (hypre_BoxVolume(rembox)) && (border[d][1]) ) { cbox = hypre_BoxArrayBox(cbox_array, cbox_array_size); hypre_CopyBox(rembox, cbox); hypre_BoxIMinD(cbox, d) = hypre_BoxIMaxD(cbox, d) - border[d][1] + 1; hypre_BoxIMaxD(rembox, d) = hypre_BoxIMaxD(cbox, d) - border[d][1]; cbox_array_size++; } } hypre_BoxArraySetSize(cbox_array, cbox_array_size); }
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_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 */
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++; } }