HYPRE_Int hypre_SStructMatvec( HYPRE_Complex alpha, hypre_SStructMatrix *A, hypre_SStructVector *x, HYPRE_Complex beta, hypre_SStructVector *y ) { void *matvec_data; hypre_SStructMatvecCreate(&matvec_data); hypre_SStructMatvecSetup(matvec_data, A, x); hypre_SStructMatvecCompute(matvec_data, alpha, A, x, beta, y); hypre_SStructMatvecDestroy(matvec_data); 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; }