HYPRE_Int hypre_SparseMSGInterp( void *interp_vdata, hypre_StructMatrix *P, hypre_StructVector *xc, hypre_StructVector *e ) { HYPRE_Int ierr = 0; hypre_SparseMSGInterpData *interp_data = interp_vdata; hypre_ComputePkg *compute_pkg; hypre_IndexRef cindex; hypre_IndexRef findex; hypre_IndexRef stride; hypre_IndexRef strideP; hypre_StructGrid *fgrid; HYPRE_Int *fgrid_ids; hypre_StructGrid *cgrid; hypre_BoxArray *cgrid_boxes; HYPRE_Int *cgrid_ids; hypre_CommHandle *comm_handle; hypre_BoxArrayArray *compute_box_aa; hypre_BoxArray *compute_box_a; hypre_Box *compute_box; hypre_Box *P_dbox; hypre_Box *xc_dbox; hypre_Box *e_dbox; HYPRE_Int Pi; HYPRE_Int xci; HYPRE_Int ei; double *Pp0, *Pp1; double *xcp; double *ep, *ep0, *ep1; hypre_Index loop_size; hypre_Index start; hypre_Index startc; hypre_Index startP; hypre_Index stridec; hypre_StructStencil *stencil; hypre_Index *stencil_shape; HYPRE_Int compute_i, fi, ci, j; HYPRE_Int loopi, loopj, loopk; /*----------------------------------------------------------------------- * Initialize some things *-----------------------------------------------------------------------*/ hypre_BeginTiming(interp_data -> time_index); compute_pkg = (interp_data -> compute_pkg); cindex = (interp_data -> cindex); findex = (interp_data -> findex); stride = (interp_data -> stride); strideP = (interp_data -> strideP); stencil = hypre_StructMatrixStencil(P); stencil_shape = hypre_StructStencilShape(stencil); hypre_SetIndex(stridec, 1, 1, 1); /*----------------------------------------------------------------------- * Compute e at coarse points (injection) *-----------------------------------------------------------------------*/ fgrid = hypre_StructVectorGrid(e); fgrid_ids = hypre_StructGridIDs(fgrid); cgrid = hypre_StructVectorGrid(xc); cgrid_boxes = hypre_StructGridBoxes(cgrid); cgrid_ids = hypre_StructGridIDs(cgrid); fi = 0; hypre_ForBoxI(ci, cgrid_boxes) { while (fgrid_ids[fi] != cgrid_ids[ci]) { fi++; } compute_box = hypre_BoxArrayBox(cgrid_boxes, ci); hypre_CopyIndex(hypre_BoxIMin(compute_box), startc); hypre_StructMapCoarseToFine(startc, cindex, stride, start); e_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(e), fi); xc_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(xc), ci); ep = hypre_StructVectorBoxData(e, fi); xcp = hypre_StructVectorBoxData(xc, ci); hypre_BoxGetSize(compute_box, loop_size); hypre_BoxLoop2Begin(loop_size, e_dbox, start, stride, ei, xc_dbox, startc, stridec, xci); #define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,ei,xci #include "hypre_box_smp_forloop.h" hypre_BoxLoop2For(loopi, loopj, loopk, ei, xci) { ep[ei] = xcp[xci]; } hypre_BoxLoop2End(ei, xci); } /*----------------------------------------------------------------------- * Compute e at fine points *-----------------------------------------------------------------------*/ for (compute_i = 0; compute_i < 2; compute_i++) { switch(compute_i) { case 0: { ep = hypre_StructVectorData(e); hypre_InitializeIndtComputations(compute_pkg, ep, &comm_handle); compute_box_aa = hypre_ComputePkgIndtBoxes(compute_pkg); } break; case 1: { hypre_FinalizeIndtComputations(comm_handle); compute_box_aa = hypre_ComputePkgDeptBoxes(compute_pkg); } break; } hypre_ForBoxArrayI(fi, compute_box_aa) { compute_box_a = hypre_BoxArrayArrayBoxArray(compute_box_aa, fi); P_dbox = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(P), fi); e_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(e), fi); Pp0 = hypre_StructMatrixBoxData(P, fi, 0); Pp1 = hypre_StructMatrixBoxData(P, fi, 1); ep = hypre_StructVectorBoxData(e, fi); ep0 = ep + hypre_BoxOffsetDistance(e_dbox, stencil_shape[0]); ep1 = ep + hypre_BoxOffsetDistance(e_dbox, stencil_shape[1]); hypre_ForBoxI(j, compute_box_a) { compute_box = hypre_BoxArrayBox(compute_box_a, j); hypre_CopyIndex(hypre_BoxIMin(compute_box), start); hypre_StructMapFineToCoarse(start, findex, stride, startc); hypre_StructMapCoarseToFine(startc, cindex, strideP, startP); hypre_BoxGetStrideSize(compute_box, stride, loop_size); hypre_BoxLoop2Begin(loop_size, P_dbox, startP, strideP, Pi, e_dbox, start, stride, ei); #define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,Pi,ei #include "hypre_box_smp_forloop.h" hypre_BoxLoop2For(loopi, loopj, loopk, Pi, ei) { ep[ei] = (Pp0[Pi] * ep0[ei] + Pp1[Pi] * ep1[ei]); } hypre_BoxLoop2End(Pi, ei); } }
HYPRE_Int hypre_SemiInterp( void *interp_vdata, hypre_StructMatrix *P, hypre_StructVector *xc, hypre_StructVector *e ) { hypre_SemiInterpData *interp_data = interp_vdata; HYPRE_Int P_stored_as_transpose; hypre_ComputePkg *compute_pkg; hypre_IndexRef cindex; hypre_IndexRef findex; hypre_IndexRef stride; hypre_StructGrid *fgrid; HYPRE_Int *fgrid_ids; hypre_StructGrid *cgrid; hypre_BoxArray *cgrid_boxes; HYPRE_Int *cgrid_ids; hypre_CommHandle *comm_handle; hypre_BoxArrayArray *compute_box_aa; hypre_BoxArray *compute_box_a; hypre_Box *compute_box; hypre_Box *P_dbox; hypre_Box *xc_dbox; hypre_Box *e_dbox; HYPRE_Int Pi; HYPRE_Int xci; HYPRE_Int ei; HYPRE_Int constant_coefficient; HYPRE_Real *Pp0, *Pp1; HYPRE_Real *xcp; HYPRE_Real *ep, *ep0, *ep1; hypre_Index loop_size; hypre_Index start; hypre_Index startc; hypre_Index stridec; hypre_StructStencil *stencil; hypre_Index *stencil_shape; HYPRE_Int compute_i, fi, ci, j; /*----------------------------------------------------------------------- * Initialize some things *-----------------------------------------------------------------------*/ hypre_BeginTiming(interp_data -> time_index); P_stored_as_transpose = (interp_data -> P_stored_as_transpose); compute_pkg = (interp_data -> compute_pkg); cindex = (interp_data -> cindex); findex = (interp_data -> findex); stride = (interp_data -> stride); stencil = hypre_StructMatrixStencil(P); stencil_shape = hypre_StructStencilShape(stencil); constant_coefficient = hypre_StructMatrixConstantCoefficient(P); hypre_assert( constant_coefficient==0 || constant_coefficient==1 ); /* ... constant_coefficient==2 for P shouldn't happen, see hypre_PFMGCreateInterpOp in pfmg_setup_interp.c */ if (constant_coefficient) hypre_StructVectorClearBoundGhostValues(e, 0); hypre_SetIndex3(stridec, 1, 1, 1); /*----------------------------------------------------------------------- * Compute e at coarse points (injection) *-----------------------------------------------------------------------*/ fgrid = hypre_StructVectorGrid(e); fgrid_ids = hypre_StructGridIDs(fgrid); cgrid = hypre_StructVectorGrid(xc); cgrid_boxes = hypre_StructGridBoxes(cgrid); cgrid_ids = hypre_StructGridIDs(cgrid); fi = 0; hypre_ForBoxI(ci, cgrid_boxes) { while (fgrid_ids[fi] != cgrid_ids[ci]) { fi++; } compute_box = hypre_BoxArrayBox(cgrid_boxes, ci); hypre_CopyIndex(hypre_BoxIMin(compute_box), startc); hypre_StructMapCoarseToFine(startc, cindex, stride, start); e_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(e), fi); xc_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(xc), ci); ep = hypre_StructVectorBoxData(e, fi); xcp = hypre_StructVectorBoxData(xc, ci); hypre_BoxGetSize(compute_box, loop_size); hypre_BoxLoop2Begin(hypre_StructMatrixNDim(P), loop_size, e_dbox, start, stride, ei, xc_dbox, startc, stridec, xci); #ifdef HYPRE_USING_OPENMP #pragma omp parallel for private(HYPRE_BOX_PRIVATE,ei,xci) HYPRE_SMP_SCHEDULE #endif hypre_BoxLoop2For(ei, xci) { ep[ei] = xcp[xci]; } hypre_BoxLoop2End(ei, xci); } /*----------------------------------------------------------------------- * Compute e at fine points *-----------------------------------------------------------------------*/ for (compute_i = 0; compute_i < 2; compute_i++) { switch(compute_i) { case 0: { ep = hypre_StructVectorData(e); hypre_InitializeIndtComputations(compute_pkg, ep, &comm_handle); compute_box_aa = hypre_ComputePkgIndtBoxes(compute_pkg); } break; case 1: { hypre_FinalizeIndtComputations(comm_handle); compute_box_aa = hypre_ComputePkgDeptBoxes(compute_pkg); } break; } hypre_ForBoxArrayI(fi, compute_box_aa) { compute_box_a = hypre_BoxArrayArrayBoxArray(compute_box_aa, fi); P_dbox = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(P), fi); e_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(e), fi); if (P_stored_as_transpose) { if ( constant_coefficient ) { Pp0 = hypre_StructMatrixBoxData(P, fi, 1); Pp1 = hypre_StructMatrixBoxData(P, fi, 0) - hypre_CCBoxOffsetDistance(P_dbox, stencil_shape[0]); } else { Pp0 = hypre_StructMatrixBoxData(P, fi, 1); Pp1 = hypre_StructMatrixBoxData(P, fi, 0) - hypre_BoxOffsetDistance(P_dbox, stencil_shape[0]); } } else { Pp0 = hypre_StructMatrixBoxData(P, fi, 0); Pp1 = hypre_StructMatrixBoxData(P, fi, 1); } ep = hypre_StructVectorBoxData(e, fi); ep0 = ep + hypre_BoxOffsetDistance(e_dbox, stencil_shape[0]); ep1 = ep + hypre_BoxOffsetDistance(e_dbox, stencil_shape[1]); hypre_ForBoxI(j, compute_box_a) { compute_box = hypre_BoxArrayBox(compute_box_a, j); hypre_CopyIndex(hypre_BoxIMin(compute_box), start); hypre_StructMapFineToCoarse(start, findex, stride, startc); hypre_BoxGetStrideSize(compute_box, stride, loop_size); if ( constant_coefficient ) { Pi = hypre_CCBoxIndexRank( P_dbox, startc ); hypre_BoxLoop1Begin(hypre_StructMatrixNDim(P), loop_size, e_dbox, start, stride, ei); #ifdef HYPRE_USING_OPENMP #pragma omp parallel for private(HYPRE_BOX_PRIVATE,ei) HYPRE_SMP_SCHEDULE #endif hypre_BoxLoop1For(ei) { ep[ei] = (Pp0[Pi] * ep0[ei] + Pp1[Pi] * ep1[ei]); } hypre_BoxLoop1End(ei); } else { hypre_BoxLoop2Begin(hypre_StructMatrixNDim(P), loop_size, P_dbox, startc, stridec, Pi, e_dbox, start, stride, ei); #ifdef HYPRE_USING_OPENMP #pragma omp parallel for private(HYPRE_BOX_PRIVATE,Pi,ei) HYPRE_SMP_SCHEDULE #endif hypre_BoxLoop2For(Pi, ei) { ep[ei] = (Pp0[Pi] * ep0[ei] + Pp1[Pi] * ep1[ei]); } hypre_BoxLoop2End(Pi, ei); } }
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_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++) */
int hypre_SemiRestrict( void *restrict_vdata, hypre_StructMatrix *R, hypre_StructVector *r, hypre_StructVector *rc ) { int ierr = 0; hypre_SemiRestrictData *restrict_data = (hypre_SemiRestrictData *)restrict_vdata; int R_stored_as_transpose; hypre_ComputePkg *compute_pkg; hypre_IndexRef cindex; hypre_IndexRef stride; hypre_StructGrid *fgrid; int *fgrid_ids; hypre_StructGrid *cgrid; hypre_BoxArray *cgrid_boxes; int *cgrid_ids; hypre_CommHandle *comm_handle; hypre_BoxArrayArray *compute_box_aa; hypre_BoxArray *compute_box_a; hypre_Box *compute_box; hypre_Box *R_dbox; hypre_Box *r_dbox; hypre_Box *rc_dbox; int Ri; int ri; int rci; double *Rp0, *Rp1; double *rp, *rp0, *rp1; double *rcp; hypre_Index loop_size; hypre_IndexRef start; hypre_Index startc; hypre_Index stridec; hypre_StructStencil *stencil; hypre_Index *stencil_shape; int compute_i, fi, ci, j; int loopi, loopj, loopk; /*----------------------------------------------------------------------- * Initialize some things. *-----------------------------------------------------------------------*/ hypre_BeginTiming(restrict_data -> time_index); R_stored_as_transpose = (restrict_data -> R_stored_as_transpose); compute_pkg = (restrict_data -> compute_pkg); cindex = (restrict_data -> cindex); stride = (restrict_data -> stride); stencil = hypre_StructMatrixStencil(R); stencil_shape = hypre_StructStencilShape(stencil); hypre_SetIndex(stridec, 1, 1, 1); /*-------------------------------------------------------------------- * Restrict the residual. *--------------------------------------------------------------------*/ fgrid = hypre_StructVectorGrid(r); fgrid_ids = hypre_StructGridIDs(fgrid); cgrid = hypre_StructVectorGrid(rc); cgrid_boxes = hypre_StructGridBoxes(cgrid); cgrid_ids = hypre_StructGridIDs(cgrid); for (compute_i = 0; compute_i < 2; compute_i++) { switch(compute_i) { case 0: { rp = hypre_StructVectorData(r); hypre_InitializeIndtComputations(compute_pkg, rp, &comm_handle); compute_box_aa = hypre_ComputePkgIndtBoxes(compute_pkg); } break; case 1: { hypre_FinalizeIndtComputations(comm_handle); compute_box_aa = hypre_ComputePkgDeptBoxes(compute_pkg); } break; } fi = 0; hypre_ForBoxArrayI(ci, cgrid_boxes) { while (fgrid_ids[fi] != cgrid_ids[ci]) { fi++; } compute_box_a = hypre_BoxArrayArrayBoxArray(compute_box_aa, fi); R_dbox = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(R), fi); r_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(r), fi); rc_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(rc), ci); if (R_stored_as_transpose) { Rp0 = hypre_StructMatrixBoxData(R, fi, 1) - hypre_BoxOffsetDistance(R_dbox, stencil_shape[1]); Rp1 = hypre_StructMatrixBoxData(R, fi, 0); } else { Rp0 = hypre_StructMatrixBoxData(R, fi, 0); Rp1 = hypre_StructMatrixBoxData(R, fi, 1); } rp = hypre_StructVectorBoxData(r, fi); rp0 = rp + hypre_BoxOffsetDistance(r_dbox, stencil_shape[0]); rp1 = rp + hypre_BoxOffsetDistance(r_dbox, stencil_shape[1]); rcp = hypre_StructVectorBoxData(rc, ci); hypre_ForBoxI(j, compute_box_a) { compute_box = hypre_BoxArrayBox(compute_box_a, j); start = hypre_BoxIMin(compute_box); hypre_StructMapFineToCoarse(start, cindex, stride, startc); hypre_BoxGetStrideSize(compute_box, stride, loop_size); hypre_BoxLoop3Begin(loop_size, R_dbox, startc, stridec, Ri, r_dbox, start, stride, ri, rc_dbox, startc, stridec, rci); #define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,Ri,ri,rci #include "hypre_box_smp_forloop.h" hypre_BoxLoop3For(loopi, loopj, loopk, Ri, ri, rci) { rcp[rci] = rp[ri] + (Rp0[Ri] * rp0[ri] + Rp1[Ri] * rp1[ri]); } hypre_BoxLoop3End(Ri, ri, rci); } }
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; }