/*-------------------------------------------------------------------------- * HYPRE_SStructFACZeroCFSten *--------------------------------------------------------------------------*/ HYPRE_Int HYPRE_SStructFACZeroCFSten( HYPRE_SStructMatrix A, HYPRE_SStructGrid grid, HYPRE_Int part, HYPRE_Int rfactors[3] ) { hypre_SStructPMatrix *Af= hypre_SStructMatrixPMatrix(A, part); hypre_SStructPMatrix *Ac= hypre_SStructMatrixPMatrix(A, part-1); return( hypre_FacZeroCFSten(Af, Ac, (hypre_SStructGrid *)grid, part, rfactors) ); }
HYPRE_Int hypre_SStructMatvecSetup( void *matvec_vdata, hypre_SStructMatrix *A, hypre_SStructVector *x ) { hypre_SStructMatvecData *matvec_data = matvec_vdata; HYPRE_Int nparts; void **pmatvec_data; hypre_SStructPMatrix *pA; hypre_SStructPVector *px; HYPRE_Int part; nparts = hypre_SStructMatrixNParts(A); pmatvec_data = hypre_TAlloc(void *, nparts); for (part = 0; part < nparts; part++) { hypre_SStructPMatvecCreate(&pmatvec_data[part]); pA = hypre_SStructMatrixPMatrix(A, part); px = hypre_SStructVectorPVector(x, part); hypre_SStructPMatvecSetup(pmatvec_data[part], pA, px); } (matvec_data -> nparts) = nparts; (matvec_data -> pmatvec_data) = pmatvec_data; return hypre_error_flag; }
/*-------------------------------------------------------------------------- * HYPRE_SStructFACZeroFCSten *--------------------------------------------------------------------------*/ HYPRE_Int HYPRE_SStructFACZeroFCSten( HYPRE_SStructMatrix A, HYPRE_SStructGrid grid, HYPRE_Int part ) { hypre_SStructPMatrix *Af= hypre_SStructMatrixPMatrix(A, part); return( hypre_FacZeroFCSten(Af, (hypre_SStructGrid *)grid, part) ); }
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_Int hypre_SysPFMGSolve( void *sys_pfmg_vdata, hypre_SStructMatrix *A_in, hypre_SStructVector *b_in, hypre_SStructVector *x_in ) { hypre_SysPFMGData *sys_pfmg_data = sys_pfmg_vdata; hypre_SStructPMatrix *A; hypre_SStructPVector *b; hypre_SStructPVector *x; double tol = (sys_pfmg_data -> tol); HYPRE_Int max_iter = (sys_pfmg_data -> max_iter); HYPRE_Int rel_change = (sys_pfmg_data -> rel_change); HYPRE_Int zero_guess = (sys_pfmg_data -> zero_guess); HYPRE_Int num_pre_relax = (sys_pfmg_data -> num_pre_relax); HYPRE_Int num_post_relax = (sys_pfmg_data -> num_post_relax); HYPRE_Int num_levels = (sys_pfmg_data -> num_levels); hypre_SStructPMatrix **A_l = (sys_pfmg_data -> A_l); hypre_SStructPMatrix **P_l = (sys_pfmg_data -> P_l); hypre_SStructPMatrix **RT_l = (sys_pfmg_data -> RT_l); hypre_SStructPVector **b_l = (sys_pfmg_data -> b_l); hypre_SStructPVector **x_l = (sys_pfmg_data -> x_l); hypre_SStructPVector **r_l = (sys_pfmg_data -> r_l); hypre_SStructPVector **e_l = (sys_pfmg_data -> e_l); void **relax_data_l = (sys_pfmg_data -> relax_data_l); void **matvec_data_l = (sys_pfmg_data -> matvec_data_l); void **restrict_data_l = (sys_pfmg_data -> restrict_data_l); void **interp_data_l = (sys_pfmg_data -> interp_data_l); HYPRE_Int logging = (sys_pfmg_data -> logging); double *norms = (sys_pfmg_data -> norms); double *rel_norms = (sys_pfmg_data -> rel_norms); HYPRE_Int *active_l = (sys_pfmg_data -> active_l); double b_dot_b, r_dot_r, eps; double e_dot_e, x_dot_x; HYPRE_Int i, l; HYPRE_Int ierr = 0; #if DEBUG char filename[255]; #endif /*----------------------------------------------------- * Initialize some things and deal with special cases *-----------------------------------------------------*/ hypre_BeginTiming(sys_pfmg_data -> time_index); /*----------------------------------------------------- * Refs to A,x,b (the PMatrix & PVectors within * the input SStructMatrix & SStructVectors) *-----------------------------------------------------*/ hypre_SStructPMatrixRef(hypre_SStructMatrixPMatrix(A_in, 0), &A); hypre_SStructPVectorRef(hypre_SStructVectorPVector(b_in, 0), &b); hypre_SStructPVectorRef(hypre_SStructVectorPVector(x_in, 0), &x); hypre_SStructPMatrixDestroy(A_l[0]); hypre_SStructPVectorDestroy(b_l[0]); hypre_SStructPVectorDestroy(x_l[0]); hypre_SStructPMatrixRef(A, &A_l[0]); hypre_SStructPVectorRef(b, &b_l[0]); hypre_SStructPVectorRef(x, &x_l[0]); (sys_pfmg_data -> num_iterations) = 0; /* if max_iter is zero, return */ if (max_iter == 0) { /* if using a zero initial guess, return zero */ if (zero_guess) { hypre_SStructPVectorSetConstantValues(x, 0.0); } hypre_EndTiming(sys_pfmg_data -> time_index); return ierr; } /* part of convergence check */ if (tol > 0.0) { /* eps = (tol^2) */ hypre_SStructPInnerProd(b_l[0], b_l[0], &b_dot_b); eps = tol*tol; /* if rhs is zero, return a zero solution */ if (b_dot_b == 0.0) { hypre_SStructPVectorSetConstantValues(x, 0.0); if (logging > 0) { norms[0] = 0.0; rel_norms[0] = 0.0; } hypre_EndTiming(sys_pfmg_data -> time_index); return ierr; } } /*----------------------------------------------------- * Do V-cycles: * For each index l, "fine" = l, "coarse" = (l+1) *-----------------------------------------------------*/ for (i = 0; i < max_iter; i++) { /*-------------------------------------------------- * Down cycle *--------------------------------------------------*/ /* fine grid pre-relaxation */ hypre_SysPFMGRelaxSetPreRelax(relax_data_l[0]); hypre_SysPFMGRelaxSetMaxIter(relax_data_l[0], num_pre_relax); hypre_SysPFMGRelaxSetZeroGuess(relax_data_l[0], zero_guess); hypre_SysPFMGRelax(relax_data_l[0], A_l[0], b_l[0], x_l[0]); zero_guess = 0; /* compute fine grid residual (b - Ax) */ hypre_SStructPCopy(b_l[0], r_l[0]); hypre_SStructPMatvecCompute(matvec_data_l[0], -1.0, A_l[0], x_l[0], 1.0, r_l[0]); /* convergence check */ if (tol > 0.0) { hypre_SStructPInnerProd(r_l[0], r_l[0], &r_dot_r); if (logging > 0) { norms[i] = sqrt(r_dot_r); if (b_dot_b > 0) rel_norms[i] = sqrt(r_dot_r/b_dot_b); else rel_norms[i] = 0.0; } /* always do at least 1 V-cycle */ if ((r_dot_r/b_dot_b < eps) && (i > 0)) { if (rel_change) { if ((e_dot_e/x_dot_x) < eps) break; } else { break; } } } if (num_levels > 1) { /* restrict fine grid residual */ hypre_SysSemiRestrict(restrict_data_l[0], RT_l[0], r_l[0], b_l[1]); #if DEBUG hypre_sprintf(filename, "zout_xdown.%02d", 0); hypre_SStructPVectorPrint(filename, x_l[0], 0); hypre_sprintf(filename, "zout_rdown.%02d", 0); hypre_SStructPVectorPrint(filename, r_l[0], 0); hypre_sprintf(filename, "zout_b.%02d", 1); hypre_SStructPVectorPrint(filename, b_l[1], 0); #endif for (l = 1; l <= (num_levels - 2); l++) { if (active_l[l]) { /* pre-relaxation */ hypre_SysPFMGRelaxSetPreRelax(relax_data_l[l]); hypre_SysPFMGRelaxSetMaxIter(relax_data_l[l], num_pre_relax); hypre_SysPFMGRelaxSetZeroGuess(relax_data_l[l], 1); hypre_SysPFMGRelax(relax_data_l[l], A_l[l], b_l[l], x_l[l]); /* compute residual (b - Ax) */ hypre_SStructPCopy(b_l[l], r_l[l]); hypre_SStructPMatvecCompute(matvec_data_l[l], -1.0, A_l[l], x_l[l], 1.0, r_l[l]); } else { /* inactive level, set x=0, so r=(b-Ax)=b */ hypre_SStructPVectorSetConstantValues(x_l[l], 0.0); hypre_SStructPCopy(b_l[l], r_l[l]); } /* restrict residual */ hypre_SysSemiRestrict(restrict_data_l[l], RT_l[l], r_l[l], b_l[l+1]); #if DEBUG hypre_sprintf(filename, "zout_xdown.%02d", l); hypre_SStructPVectorPrint(filename, x_l[l], 0); hypre_sprintf(filename, "zout_rdown.%02d", l); hypre_SStructPVectorPrint(filename, r_l[l], 0); hypre_sprintf(filename, "zout_b.%02d", l+1); hypre_SStructPVectorPrint(filename, b_l[l+1], 0); #endif } /*-------------------------------------------------- * Bottom *--------------------------------------------------*/ hypre_SysPFMGRelaxSetZeroGuess(relax_data_l[l], 1); hypre_SysPFMGRelax(relax_data_l[l], A_l[l], b_l[l], x_l[l]); #if DEBUG hypre_sprintf(filename, "zout_xbottom.%02d", l); hypre_SStructPVectorPrint(filename, x_l[l], 0); #endif /*-------------------------------------------------- * Up cycle *--------------------------------------------------*/ for (l = (num_levels - 2); l >= 1; l--) { /* interpolate error and correct (x = x + Pe_c) */ hypre_SysSemiInterp(interp_data_l[l], P_l[l], x_l[l+1], e_l[l]); hypre_SStructPAxpy(1.0, e_l[l], x_l[l]); #if DEBUG hypre_sprintf(filename, "zout_eup.%02d", l); hypre_SStructPVectorPrint(filename, e_l[l], 0); hypre_sprintf(filename, "zout_xup.%02d", l); hypre_SStructPVectorPrint(filename, x_l[l], 0); #endif if (active_l[l]) { /* post-relaxation */ hypre_SysPFMGRelaxSetPostRelax(relax_data_l[l]); hypre_SysPFMGRelaxSetMaxIter(relax_data_l[l], num_post_relax); hypre_SysPFMGRelaxSetZeroGuess(relax_data_l[l], 0); hypre_SysPFMGRelax(relax_data_l[l], A_l[l], b_l[l], x_l[l]); } } /* interpolate error and correct on fine grid (x = x + Pe_c) */ hypre_SysSemiInterp(interp_data_l[0], P_l[0], x_l[1], e_l[0]); hypre_SStructPAxpy(1.0, e_l[0], x_l[0]); #if DEBUG hypre_sprintf(filename, "zout_eup.%02d", 0); hypre_SStructPVectorPrint(filename, e_l[0], 0); hypre_sprintf(filename, "zout_xup.%02d", 0); hypre_SStructPVectorPrint(filename, x_l[0], 0); #endif } /* part of convergence check */ if ((tol > 0.0) && (rel_change)) { if (num_levels > 1) { hypre_SStructPInnerProd(e_l[0], e_l[0], &e_dot_e); hypre_SStructPInnerProd(x_l[0], x_l[0], &x_dot_x); } else { e_dot_e = 0.0; x_dot_x = 1.0; } } /* fine grid post-relaxation */ hypre_SysPFMGRelaxSetPostRelax(relax_data_l[0]); hypre_SysPFMGRelaxSetMaxIter(relax_data_l[0], num_post_relax); hypre_SysPFMGRelaxSetZeroGuess(relax_data_l[0], 0); hypre_SysPFMGRelax(relax_data_l[0], A_l[0], b_l[0], x_l[0]); (sys_pfmg_data -> num_iterations) = (i + 1); } /*----------------------------------------------------- * Destroy Refs to A,x,b (the PMatrix & PVectors within * the input SStructMatrix & SStructVectors). *-----------------------------------------------------*/ hypre_SStructPMatrixDestroy(A); hypre_SStructPVectorDestroy(x); hypre_SStructPVectorDestroy(b); hypre_EndTiming(sys_pfmg_data -> time_index); return ierr; }
HYPRE_Int hypre_SStructMatvecCompute( void *matvec_vdata, HYPRE_Complex alpha, hypre_SStructMatrix *A, hypre_SStructVector *x, HYPRE_Complex beta, hypre_SStructVector *y ) { hypre_SStructMatvecData *matvec_data = matvec_vdata; HYPRE_Int nparts = (matvec_data -> nparts); void **pmatvec_data = (matvec_data -> pmatvec_data); void *pdata; hypre_SStructPMatrix *pA; hypre_SStructPVector *px; hypre_SStructPVector *py; hypre_ParCSRMatrix *parcsrA = hypre_SStructMatrixParCSRMatrix(A); hypre_ParVector *parx; hypre_ParVector *pary; HYPRE_Int part; HYPRE_Int x_object_type= hypre_SStructVectorObjectType(x); HYPRE_Int A_object_type= hypre_SStructMatrixObjectType(A); if (x_object_type != A_object_type) { hypre_error_in_arg(2); hypre_error_in_arg(3); return hypre_error_flag; } if ( (x_object_type == HYPRE_SSTRUCT) || (x_object_type == HYPRE_STRUCT) ) { /* do S-matrix computations */ for (part = 0; part < nparts; part++) { pdata = pmatvec_data[part]; pA = hypre_SStructMatrixPMatrix(A, part); px = hypre_SStructVectorPVector(x, part); py = hypre_SStructVectorPVector(y, part); hypre_SStructPMatvecCompute(pdata, alpha, pA, px, beta, py); } if (x_object_type == HYPRE_SSTRUCT) { /* do U-matrix computations */ /* GEC1002 the data chunk pointed by the local-parvectors * inside the semistruct vectors x and y is now identical to the * data chunk of the structure vectors x and y. The role of the function * convert is to pass the addresses of the data chunk * to the parx and pary. */ hypre_SStructVectorConvert(x, &parx); hypre_SStructVectorConvert(y, &pary); hypre_ParCSRMatrixMatvec(alpha, parcsrA, parx, 1.0, pary); /* dummy functions since there is nothing to restore */ hypre_SStructVectorRestore(x, NULL); hypre_SStructVectorRestore(y, pary); parx = NULL; } } else if (x_object_type == HYPRE_PARCSR) { hypre_SStructVectorConvert(x, &parx); hypre_SStructVectorConvert(y, &pary); hypre_ParCSRMatrixMatvec(alpha, parcsrA, parx, beta, pary); hypre_SStructVectorRestore(x, NULL); hypre_SStructVectorRestore(y, pary); parx = NULL; } return hypre_error_flag; }
HYPRE_Int HYPRE_SStructSplitSolve( HYPRE_SStructSolver solver, HYPRE_SStructMatrix A, HYPRE_SStructVector b, HYPRE_SStructVector x ) { hypre_SStructVector *y = (solver -> y); HYPRE_Int nparts = (solver -> nparts); HYPRE_Int *nvars = (solver -> nvars); void ****smatvec_data = (solver -> smatvec_data); HYPRE_Int (***ssolver_solve)() = (solver -> ssolver_solve); void ***ssolver_data = (solver -> ssolver_data); double tol = (solver -> tol); HYPRE_Int max_iter = (solver -> max_iter); HYPRE_Int zero_guess = (solver -> zero_guess); void *matvec_data = (solver -> matvec_data); hypre_SStructPMatrix *pA; hypre_SStructPVector *px; hypre_SStructPVector *py; hypre_StructMatrix *sA; hypre_StructVector *sx; hypre_StructVector *sy; HYPRE_Int (*ssolve)(); void *sdata; hypre_ParCSRMatrix *parcsrA; hypre_ParVector *parx; hypre_ParVector *pary; HYPRE_Int iter, part, vi, vj; double b_dot_b = 0, r_dot_r; /* part of convergence check */ if (tol > 0.0) { /* eps = (tol^2) */ hypre_SStructInnerProd(b, b, &b_dot_b); /* if rhs is zero, return a zero solution */ if (b_dot_b == 0.0) { hypre_SStructVectorSetConstantValues(x, 0.0); (solver -> rel_norm) = 0.0; return hypre_error_flag; } } for (iter = 0; iter < max_iter; iter++) { /* convergence check */ if (tol > 0.0) { /* compute fine grid residual (b - Ax) */ hypre_SStructCopy(b, y); hypre_SStructMatvecCompute(matvec_data, -1.0, A, x, 1.0, y); hypre_SStructInnerProd(y, y, &r_dot_r); (solver -> rel_norm) = sqrt(r_dot_r/b_dot_b); if ((solver -> rel_norm) < tol) { break; } } /* copy b into y */ hypre_SStructCopy(b, y); /* compute y = y + Nx */ if (!zero_guess || (iter > 0)) { for (part = 0; part < nparts; part++) { pA = hypre_SStructMatrixPMatrix(A, part); px = hypre_SStructVectorPVector(x, part); py = hypre_SStructVectorPVector(y, part); for (vi = 0; vi < nvars[part]; vi++) { for (vj = 0; vj < nvars[part]; vj++) { sdata = smatvec_data[part][vi][vj]; sy = hypre_SStructPVectorSVector(py, vi); if ((sdata != NULL) && (vj != vi)) { sA = hypre_SStructPMatrixSMatrix(pA, vi, vj); sx = hypre_SStructPVectorSVector(px, vj); hypre_StructMatvecCompute(sdata, -1.0, sA, sx, 1.0, sy); } } } } parcsrA = hypre_SStructMatrixParCSRMatrix(A); hypre_SStructVectorConvert(x, &parx); hypre_SStructVectorConvert(y, &pary); hypre_ParCSRMatrixMatvec(-1.0, parcsrA, parx, 1.0, pary); hypre_SStructVectorRestore(x, NULL); hypre_SStructVectorRestore(y, pary); } /* compute x = M^{-1} y */ for (part = 0; part < nparts; part++) { pA = hypre_SStructMatrixPMatrix(A, part); px = hypre_SStructVectorPVector(x, part); py = hypre_SStructVectorPVector(y, part); for (vi = 0; vi < nvars[part]; vi++) { ssolve = ssolver_solve[part][vi]; sdata = ssolver_data[part][vi]; sA = hypre_SStructPMatrixSMatrix(pA, vi, vi); sx = hypre_SStructPVectorSVector(px, vi); sy = hypre_SStructPVectorSVector(py, vi); ssolve(sdata, sA, sy, sx); } } } (solver -> num_iterations) = iter; return hypre_error_flag; }
HYPRE_Int HYPRE_SStructSplitSetup( HYPRE_SStructSolver solver, HYPRE_SStructMatrix A, HYPRE_SStructVector b, HYPRE_SStructVector x ) { hypre_SStructVector *y; HYPRE_Int nparts; HYPRE_Int *nvars; void ****smatvec_data; HYPRE_Int (***ssolver_solve)(); HYPRE_Int (***ssolver_destroy)(); void ***ssolver_data; HYPRE_Int ssolver = (solver -> ssolver); MPI_Comm comm; hypre_SStructGrid *grid; hypre_SStructPMatrix *pA; hypre_SStructPVector *px; hypre_SStructPVector *py; hypre_StructMatrix *sA; hypre_StructVector *sx; hypre_StructVector *sy; HYPRE_StructMatrix sAH; HYPRE_StructVector sxH; HYPRE_StructVector syH; HYPRE_Int (*ssolve)(); HYPRE_Int (*sdestroy)(); void *sdata; HYPRE_Int part, vi, vj; comm = hypre_SStructVectorComm(b); grid = hypre_SStructVectorGrid(b); HYPRE_SStructVectorCreate(comm, grid, &y); HYPRE_SStructVectorInitialize(y); HYPRE_SStructVectorAssemble(y); nparts = hypre_SStructMatrixNParts(A); nvars = hypre_TAlloc(HYPRE_Int, nparts); smatvec_data = hypre_TAlloc(void ***, nparts); ssolver_solve = (HYPRE_Int (***)()) hypre_MAlloc((sizeof(HYPRE_Int (**)()) * nparts)); ssolver_destroy = (HYPRE_Int (***)()) hypre_MAlloc((sizeof(HYPRE_Int (**)()) * nparts)); ssolver_data = hypre_TAlloc(void **, nparts); for (part = 0; part < nparts; part++) { pA = hypre_SStructMatrixPMatrix(A, part); px = hypre_SStructVectorPVector(x, part); py = hypre_SStructVectorPVector(y, part); nvars[part] = hypre_SStructPMatrixNVars(pA); smatvec_data[part] = hypre_TAlloc(void **, nvars[part]); ssolver_solve[part] = (HYPRE_Int (**)()) hypre_MAlloc((sizeof(HYPRE_Int (*)()) * nvars[part])); ssolver_destroy[part] = (HYPRE_Int (**)()) hypre_MAlloc((sizeof(HYPRE_Int (*)()) * nvars[part])); ssolver_data[part] = hypre_TAlloc(void *, nvars[part]); for (vi = 0; vi < nvars[part]; vi++) { smatvec_data[part][vi] = hypre_TAlloc(void *, nvars[part]); for (vj = 0; vj < nvars[part]; vj++) { sA = hypre_SStructPMatrixSMatrix(pA, vi, vj); sx = hypre_SStructPVectorSVector(px, vj); smatvec_data[part][vi][vj] = NULL; if (sA != NULL) { smatvec_data[part][vi][vj] = hypre_StructMatvecCreate(); hypre_StructMatvecSetup(smatvec_data[part][vi][vj], sA, sx); } } sA = hypre_SStructPMatrixSMatrix(pA, vi, vi); sx = hypre_SStructPVectorSVector(px, vi); sy = hypre_SStructPVectorSVector(py, vi); sAH = (HYPRE_StructMatrix) sA; sxH = (HYPRE_StructVector) sx; syH = (HYPRE_StructVector) sy; switch(ssolver) { default: /* If no solver is matched, use Jacobi, but throw and error */ if (ssolver != HYPRE_Jacobi) { hypre_error(HYPRE_ERROR_GENERIC); } /* don't break */ case HYPRE_Jacobi: HYPRE_StructJacobiCreate(comm, (HYPRE_StructSolver *)&sdata); HYPRE_StructJacobiSetMaxIter(sdata, 1); HYPRE_StructJacobiSetTol(sdata, 0.0); if (solver -> zero_guess) { HYPRE_StructJacobiSetZeroGuess(sdata); } HYPRE_StructJacobiSetup(sdata, sAH, syH, sxH); ssolve = HYPRE_StructJacobiSolve; sdestroy = HYPRE_StructJacobiDestroy; break; case HYPRE_SMG: HYPRE_StructSMGCreate(comm, (HYPRE_StructSolver *)&sdata); HYPRE_StructSMGSetMemoryUse(sdata, 0); HYPRE_StructSMGSetMaxIter(sdata, 1); HYPRE_StructSMGSetTol(sdata, 0.0); if (solver -> zero_guess) { HYPRE_StructSMGSetZeroGuess(sdata); } HYPRE_StructSMGSetNumPreRelax(sdata, 1); HYPRE_StructSMGSetNumPostRelax(sdata, 1); HYPRE_StructSMGSetLogging(sdata, 0); HYPRE_StructSMGSetPrintLevel(sdata, 0); HYPRE_StructSMGSetup(sdata, sAH, syH, sxH); ssolve = HYPRE_StructSMGSolve; sdestroy = HYPRE_StructSMGDestroy; break; case HYPRE_PFMG: HYPRE_StructPFMGCreate(comm, (HYPRE_StructSolver *)&sdata); HYPRE_StructPFMGSetMaxIter(sdata, 1); HYPRE_StructPFMGSetTol(sdata, 0.0); if (solver -> zero_guess) { HYPRE_StructPFMGSetZeroGuess(sdata); } HYPRE_StructPFMGSetRelaxType(sdata, 1); HYPRE_StructPFMGSetNumPreRelax(sdata, 1); HYPRE_StructPFMGSetNumPostRelax(sdata, 1); HYPRE_StructPFMGSetLogging(sdata, 0); HYPRE_StructPFMGSetPrintLevel(sdata, 0); HYPRE_StructPFMGSetup(sdata, sAH, syH, sxH); ssolve = HYPRE_StructPFMGSolve; sdestroy = HYPRE_StructPFMGDestroy; break; } ssolver_solve[part][vi] = ssolve; ssolver_destroy[part][vi] = sdestroy; ssolver_data[part][vi] = sdata; } } (solver -> y) = y; (solver -> nparts) = nparts; (solver -> nvars) = nvars; (solver -> smatvec_data) = smatvec_data; (solver -> ssolver_solve) = ssolver_solve; (solver -> ssolver_destroy) = ssolver_destroy; (solver -> ssolver_data) = ssolver_data; if ((solver -> tol) > 0.0) { hypre_SStructMatvecCreate(&(solver -> matvec_data)); hypre_SStructMatvecSetup((solver -> matvec_data), A, x); } return hypre_error_flag; }
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++) */