void hypre_F90_IFACE(hypre_structsmgsetnumprerelax, HYPRE_STRUCTSMGSETNUMPRERELAX) ( hypre_F90_Obj *solver, hypre_F90_Int *num_pre_relax, hypre_F90_Int *ierr ) { *ierr = (hypre_F90_Int) ( HYPRE_StructSMGSetNumPreRelax( hypre_F90_PassObj (HYPRE_StructSolver, solver), hypre_F90_PassInt (num_pre_relax)) ); }
double *solve(double *Ab, int solver_id, struct parms parms) { int i, j; double final_res_norm; int time_index, n_pre, n_post, num_iterations; n_pre = 1; n_post = 1; double *A_val, *b_val; A_val = (double *) calloc(parms.N*parms.nsten, sizeof(double)); b_val = (double *) calloc(parms.N, sizeof(double)); for (i = 0; i < (parms.N*parms.nsten); i++){ A_val[i] = Ab[i]; } for (i = 0; i < parms.N; i++){ b_val[i] = Ab[i+parms.N*parms.nsten]; } // HYPRE // HYPRE_StructGrid grid; HYPRE_StructStencil stencil; HYPRE_StructMatrix A; HYPRE_StructVector b; HYPRE_StructVector x; HYPRE_StructSolver solver; HYPRE_StructSolver precond; #if Dim == 2 HYPRE_Int ilower[2] = {parms.x0, parms.y0}; HYPRE_Int iupper[2] = {parms.x1, parms.y1}; #endif #if Dim == 3 HYPRE_Int ilower[3] = {parms.x0, parms.y0, 0}; HYPRE_Int iupper[3] = {parms.x1, parms.y1, parms.Nz-1}; #endif { // Create an empty 2D grid object HYPRE_StructGridCreate(MPI_COMM_WORLD, Dim, &grid); // Add a new box to the grid HYPRE_StructGridSetExtents(grid, ilower, iupper); // 1. Set up periodic boundary condition in y-direction and create the grid int pset[3]; pset[0] = 0; pset[1] = parms.Ny; pset[2] = 0; #if Dim == 3 pset[2] = parms.Nz; #endif //HYPRE_StructGridSetNumGhost(grid,pset) HYPRE_StructGridSetPeriodic(grid, pset); HYPRE_StructGridAssemble(grid); } // 2. Define the discretization stencil { if (Dim == 2){ // Create an empty 2D, 5-pt stencil object HYPRE_StructStencilCreate(2, parms.nsten, &stencil); // Define the geometry of the stencil { int offsets[5][2] = {{0,0}, {-1,0}, {0,-1}, {0,1}, {1,0}}; for (i = 0; i < parms.nsten; i++) HYPRE_StructStencilSetElement(stencil, i, offsets[i]); } } else { HYPRE_StructStencilCreate(3, parms.nsten, &stencil); // Define the geometry of the 3D stencil { int offsets[7][3] = {{0,0,0}, {-1,0,0}, {0,-1,0}, {0,1,0}, {1,0,0}, {0,0,-1}, {0,0,1}}; for (i = 0; i < parms.nsten; i++) HYPRE_StructStencilSetElement(stencil, i, offsets[i]); } } } // 3. Set up a Struct Matrix A from Aval { HYPRE_Int stencil_indices[parms.nsten]; // Create an empty matrix object HYPRE_StructMatrixCreate(MPI_COMM_WORLD, grid, stencil, &A); // Indicate that the matrix coefficients are ready to be set HYPRE_StructMatrixInitialize(A); for (j = 0; j < parms.nsten; j++) stencil_indices[j] = j; HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, parms.nsten, stencil_indices, A_val); free(A_val); } // 4. Set up Struct Vectors for b from b_val and set x = 0 { double *values; HYPRE_StructVectorCreate(MPI_COMM_WORLD, grid, &b); HYPRE_StructVectorCreate(MPI_COMM_WORLD, grid, &x); HYPRE_StructVectorInitialize(b); HYPRE_StructVectorInitialize(x); values = calloc((parms.N), sizeof(double)); for (i = 0; i < (parms.N); i++) values[i] = 0.0; HYPRE_StructVectorSetBoxValues(x, ilower, iupper, values); HYPRE_StructVectorSetBoxValues(b, ilower, iupper, b_val); free(b_val); free(values); } //Finalize the vector and matrix assembly HYPRE_StructMatrixAssemble(A); HYPRE_StructVectorAssemble(b); HYPRE_StructVectorAssemble(x); #if DEBUG == 3 HYPRE_StructMatrixPrint("./poisson.matrix", A, 0); HYPRE_StructVectorPrint("./poisson.rhs", b, 0); /*char fname[64]; char Aname[64], bname[64]; sprintf(Aname,"data/A%d.",parms.cyc); sprintf(bname,"data/b%d.",parms.cyc); filename(fname, Aname, parms.wkdir, parms); HYPRE_StructMatrixPrint(fname, A, 0); filename(fname, bname, parms.wkdir, parms); HYPRE_StructVectorPrint(fname, b, 0);*/ #endif // 6. Set up and use a solver (SMG) if (solver_id == 0) { time_index = hypre_InitializeTiming("SMG Setup"); hypre_BeginTiming(time_index); HYPRE_StructSMGCreate(MPI_COMM_WORLD, &solver); HYPRE_StructSMGSetMemoryUse(solver, 0); HYPRE_StructSMGSetMaxIter(solver, 100); HYPRE_StructSMGSetTol(solver, 1.0e-12); HYPRE_StructSMGSetRelChange(solver, 0); HYPRE_StructSMGSetNumPreRelax(solver, n_pre); HYPRE_StructSMGSetNumPostRelax(solver, n_post); // Logging must be on to get iterations and residual norm info below HYPRE_StructSMGSetLogging(solver, 1); // Setup and print setup timings HYPRE_StructSMGSetup(solver, A, b, x); hypre_EndTiming(time_index); #if DEBUG == 3 hypre_PrintTiming("Setup phase times", MPI_COMM_WORLD); #endif hypre_FinalizeTiming(time_index); hypre_ClearTiming(); // Solve and print solve timings time_index = hypre_InitializeTiming("SMG Solve"); hypre_BeginTiming(time_index); HYPRE_StructSMGSolve(solver, A, b, x); hypre_EndTiming(time_index); #if DEBUG == 3 hypre_PrintTiming("Solve phase times", MPI_COMM_WORLD); #endif hypre_FinalizeTiming(time_index); hypre_ClearTiming(); // Get some info on the run HYPRE_StructSMGGetNumIterations(solver, &num_iterations); HYPRE_StructSMGGetFinalRelativeResidualNorm(solver, &final_res_norm); #if DEBUG == 2 if (parms.rank == 0){ fprintf(stdout, "Number of Iterations = %4d ; Final Relative Residual Norm = %e\n\n", num_iterations, final_res_norm); } #endif // Clean up HYPRE_StructSMGDestroy(solver); } // 6. Set up and use a solver (PCG) with SMG Preconditioner if (solver_id == 1) { HYPRE_StructPCGCreate(MPI_COMM_WORLD, &solver); //HYPRE_StructPCGSetMemoryUse(solver, 0); HYPRE_StructPCGSetMaxIter(solver, 100); HYPRE_StructPCGSetTol(solver, 1.0e-12); HYPRE_StructPCGSetTwoNorm(solver, 1); HYPRE_StructPCGSetRelChange(solver, 0); //HYPRE_StructPCGSetPrintLevel(solver, 2 ); /* print each CG iteration */ HYPRE_StructPCGSetLogging(solver, 1); /* Use symmetric SMG as preconditioner */ HYPRE_StructSMGCreate(MPI_COMM_WORLD, &precond); HYPRE_StructSMGSetMemoryUse(precond, 0); HYPRE_StructSMGSetMaxIter(precond, 32); HYPRE_StructSMGSetTol(precond, 0.0); HYPRE_StructSMGSetZeroGuess(precond); HYPRE_StructSMGSetNumPreRelax(precond, 1); HYPRE_StructSMGSetNumPostRelax(precond, 1); /* Set the preconditioner and solve */ HYPRE_StructPCGSetPrecond(solver, HYPRE_StructSMGSolve, HYPRE_StructSMGSetup, precond); HYPRE_StructPCGSetup(solver, A, b, x); HYPRE_StructPCGSolve(solver, A, b, x); /* Get some info on the run */ HYPRE_StructPCGGetNumIterations(solver, &num_iterations); HYPRE_StructPCGGetFinalRelativeResidualNorm(solver, &final_res_norm); #if DEBUG == 2 if (parms.rank == 0){ fprintf(stdout, "Number of Iterations = %4d ; Final Relative Residual Norm = %e\n\n", num_iterations, final_res_norm); } #endif /* Clean up */ HYPRE_StructSMGDestroy(precond); HYPRE_StructPCGDestroy(solver); } // get the local solution double *values = calloc(parms.N, sizeof(double)); HYPRE_StructVectorGetBoxValues(x, ilower, iupper, values); // Free memory HYPRE_StructGridDestroy(grid); HYPRE_StructStencilDestroy(stencil); HYPRE_StructMatrixDestroy(A); HYPRE_StructVectorDestroy(b); HYPRE_StructVectorDestroy(x); free(Ab); return(values); }
void CCDivGradHypreLevelSolver::setupHypreSolver() { // Get the MPI communicator. #ifdef HAVE_MPI MPI_Comm communicator = SAMRAI_MPI::getCommunicator(); #else MPI_Comm communicator; #endif // When using a Krylov method, setup the preconditioner. if (d_solver_type == "PCG" || d_solver_type == "GMRES" || d_solver_type == "FlexGMRES" || d_solver_type == "LGMRES" || d_solver_type == "BiCGSTAB") { if (d_precond_type == "PFMG") { HYPRE_StructPFMGCreate(communicator, &d_precond); HYPRE_StructPFMGSetMaxIter(d_precond, 1); HYPRE_StructPFMGSetTol(d_precond, 0.0); HYPRE_StructPFMGSetZeroGuess(d_precond); HYPRE_StructPFMGSetRAPType(d_precond, d_rap_type); HYPRE_StructPFMGSetRelaxType(d_precond, d_relax_type); HYPRE_StructPFMGSetNumPreRelax(d_precond, d_num_pre_relax_steps); HYPRE_StructPFMGSetNumPostRelax(d_precond, d_num_post_relax_steps); HYPRE_StructPFMGSetSkipRelax(d_precond, d_skip_relax); } else if (d_precond_type == "SMG") { HYPRE_StructSMGCreate(communicator, &d_precond); HYPRE_StructSMGSetMaxIter(d_precond, 1); HYPRE_StructSMGSetTol(d_precond, 0.0); HYPRE_StructSMGSetZeroGuess(d_precond); HYPRE_StructSMGSetMemoryUse(d_precond, d_memory_use); HYPRE_StructSMGSetNumPreRelax(d_precond, d_num_pre_relax_steps); HYPRE_StructSMGSetNumPostRelax(d_precond, d_num_post_relax_steps); } else if (d_precond_type == "Jacobi") { HYPRE_StructJacobiCreate(communicator, &d_precond); HYPRE_StructJacobiSetMaxIter(d_precond, 2); HYPRE_StructJacobiSetTol(d_precond, 0.0); HYPRE_StructJacobiSetZeroGuess(d_precond); } } // Setup the solver. if (d_solver_type == "PFMG") { HYPRE_StructPFMGCreate(communicator, &d_solver); HYPRE_StructPFMGSetMaxIter(d_solver, d_max_iterations); HYPRE_StructPFMGSetTol(d_solver, d_rel_residual_tol); HYPRE_StructPFMGSetRelChange(d_solver, d_rel_change); HYPRE_StructPFMGSetRAPType(d_solver, d_rap_type); HYPRE_StructPFMGSetRelaxType(d_solver, d_relax_type); HYPRE_StructPFMGSetNumPreRelax(d_solver, d_num_pre_relax_steps); HYPRE_StructPFMGSetNumPostRelax(d_solver, d_num_post_relax_steps); HYPRE_StructPFMGSetSkipRelax(d_solver, d_skip_relax); if (d_initial_guess_nonzero) { HYPRE_StructPFMGSetNonZeroGuess(d_solver); } else { HYPRE_StructPFMGSetZeroGuess(d_solver); } HYPRE_StructPFMGSetup(d_solver, d_matrix, d_rhs_vec, d_sol_vec); } else if (d_solver_type == "SMG") { HYPRE_StructSMGCreate(communicator, &d_solver); HYPRE_StructSMGSetMaxIter(d_solver, d_max_iterations); HYPRE_StructSMGSetTol(d_solver, d_rel_residual_tol); HYPRE_StructSMGSetRelChange(d_solver, d_rel_change); HYPRE_StructSMGSetMemoryUse(d_solver, d_memory_use); HYPRE_StructSMGSetNumPreRelax(d_solver, d_num_pre_relax_steps); HYPRE_StructSMGSetNumPostRelax(d_solver, d_num_post_relax_steps); if (d_initial_guess_nonzero) { HYPRE_StructSMGSetNonZeroGuess(d_solver); } else { HYPRE_StructSMGSetZeroGuess(d_solver); } HYPRE_StructSMGSetup(d_solver, d_matrix, d_rhs_vec, d_sol_vec); } else if (d_solver_type == "PCG") { HYPRE_StructPCGCreate(communicator, &d_solver); HYPRE_StructPCGSetMaxIter(d_solver, d_max_iterations); HYPRE_StructPCGSetTol(d_solver, d_rel_residual_tol); HYPRE_StructPCGSetAbsoluteTol(d_solver, d_abs_residual_tol); HYPRE_StructPCGSetTwoNorm(d_solver, d_two_norm); HYPRE_StructPCGSetRelChange(d_solver, d_rel_change); if (d_precond_type == "PFMG") { HYPRE_StructPCGSetPrecond(d_solver, HYPRE_StructPFMGSolve, HYPRE_StructPFMGSetup, d_precond); } else if (d_precond_type == "SMG") { HYPRE_StructPCGSetPrecond(d_solver, HYPRE_StructSMGSolve, HYPRE_StructSMGSetup, d_precond); } else if (d_precond_type == "Jacobi") { HYPRE_StructPCGSetPrecond(d_solver, HYPRE_StructJacobiSolve, HYPRE_StructJacobiSetup, d_precond); } else if (d_precond_type == "diagonal_scaling") { d_precond = NULL; HYPRE_StructPCGSetPrecond(d_solver, HYPRE_StructDiagScale, HYPRE_StructDiagScaleSetup, d_precond); } else if (d_precond_type == "none") { d_precond = NULL; } else { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " unknown preconditioner type: " << d_precond_type << std::endl); } HYPRE_StructPCGSetup(d_solver, d_matrix, d_rhs_vec, d_sol_vec); } else if (d_solver_type == "GMRES") { HYPRE_StructGMRESCreate(communicator, &d_solver); HYPRE_StructGMRESSetMaxIter(d_solver, d_max_iterations); HYPRE_StructGMRESSetTol(d_solver, d_rel_residual_tol); HYPRE_StructGMRESSetAbsoluteTol(d_solver, d_abs_residual_tol); if (d_precond_type == "PFMG") { HYPRE_StructGMRESSetPrecond(d_solver, HYPRE_StructPFMGSolve, HYPRE_StructPFMGSetup, d_precond); } else if (d_precond_type == "SMG") { HYPRE_StructGMRESSetPrecond(d_solver, HYPRE_StructSMGSolve, HYPRE_StructSMGSetup, d_precond); } else if (d_precond_type == "Jacobi") { HYPRE_StructGMRESSetPrecond(d_solver, HYPRE_StructJacobiSolve, HYPRE_StructJacobiSetup, d_precond); } else if (d_precond_type == "diagonal_scaling") { d_precond = NULL; HYPRE_StructGMRESSetPrecond(d_solver, HYPRE_StructDiagScale, HYPRE_StructDiagScaleSetup, d_precond); } else if (d_precond_type == "none") { d_precond = NULL; } else { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " unknown preconditioner type: " << d_precond_type << std::endl); } HYPRE_StructGMRESSetup(d_solver, d_matrix, d_rhs_vec, d_sol_vec); } else if (d_solver_type == "FlexGMRES") { HYPRE_StructFlexGMRESCreate(communicator, &d_solver); HYPRE_StructFlexGMRESSetMaxIter(d_solver, d_max_iterations); HYPRE_StructFlexGMRESSetTol(d_solver, d_rel_residual_tol); HYPRE_StructFlexGMRESSetAbsoluteTol(d_solver, d_abs_residual_tol); if (d_precond_type == "PFMG") { HYPRE_StructFlexGMRESSetPrecond(d_solver, HYPRE_StructPFMGSolve, HYPRE_StructPFMGSetup, d_precond); } else if (d_precond_type == "SMG") { HYPRE_StructFlexGMRESSetPrecond(d_solver, HYPRE_StructSMGSolve, HYPRE_StructSMGSetup, d_precond); } else if (d_precond_type == "Jacobi") { HYPRE_StructFlexGMRESSetPrecond(d_solver, HYPRE_StructJacobiSolve, HYPRE_StructJacobiSetup, d_precond); } else if (d_precond_type == "diagonal_scaling") { d_precond = NULL; HYPRE_StructFlexGMRESSetPrecond(d_solver, HYPRE_StructDiagScale, HYPRE_StructDiagScaleSetup, d_precond); } else if (d_precond_type == "none") { d_precond = NULL; } else { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " unknown preconditioner type: " << d_precond_type << std::endl); } HYPRE_StructFlexGMRESSetup(d_solver, d_matrix, d_rhs_vec, d_sol_vec); } else if (d_solver_type == "LGMRES") { HYPRE_StructLGMRESCreate(communicator, &d_solver); HYPRE_StructLGMRESSetMaxIter(d_solver, d_max_iterations); HYPRE_StructLGMRESSetTol(d_solver, d_rel_residual_tol); HYPRE_StructLGMRESSetAbsoluteTol(d_solver, d_abs_residual_tol); if (d_precond_type == "PFMG") { HYPRE_StructLGMRESSetPrecond(d_solver, HYPRE_StructPFMGSolve, HYPRE_StructPFMGSetup, d_precond); } else if (d_precond_type == "SMG") { HYPRE_StructLGMRESSetPrecond(d_solver, HYPRE_StructSMGSolve, HYPRE_StructSMGSetup, d_precond); } else if (d_precond_type == "Jacobi") { HYPRE_StructLGMRESSetPrecond(d_solver, HYPRE_StructJacobiSolve, HYPRE_StructJacobiSetup, d_precond); } else if (d_precond_type == "diagonal_scaling") { d_precond = NULL; HYPRE_StructLGMRESSetPrecond(d_solver, HYPRE_StructDiagScale, HYPRE_StructDiagScaleSetup, d_precond); } else if (d_precond_type == "none") { d_precond = NULL; } else { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " unknown preconditioner type: " << d_precond_type << std::endl); } HYPRE_StructLGMRESSetup(d_solver, d_matrix, d_rhs_vec, d_sol_vec); } else if (d_solver_type == "BiCGSTAB") { HYPRE_StructBiCGSTABCreate(communicator, &d_solver); HYPRE_StructBiCGSTABSetMaxIter(d_solver, d_max_iterations); HYPRE_StructBiCGSTABSetTol(d_solver, d_rel_residual_tol); HYPRE_StructBiCGSTABSetAbsoluteTol(d_solver, d_abs_residual_tol); if (d_precond_type == "PFMG") { HYPRE_StructBiCGSTABSetPrecond(d_solver, HYPRE_StructPFMGSolve, HYPRE_StructPFMGSetup, d_precond); } else if (d_precond_type == "SMG") { HYPRE_StructBiCGSTABSetPrecond(d_solver, HYPRE_StructSMGSolve, HYPRE_StructSMGSetup, d_precond); } else if (d_precond_type == "Jacobi") { HYPRE_StructBiCGSTABSetPrecond(d_solver, HYPRE_StructJacobiSolve, HYPRE_StructJacobiSetup, d_precond); } else if (d_precond_type == "diagonal_scaling") { d_precond = NULL; HYPRE_StructBiCGSTABSetPrecond(d_solver, HYPRE_StructDiagScale, HYPRE_StructDiagScaleSetup, d_precond); } else if (d_precond_type == "none") { d_precond = NULL; } else { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " unknown preconditioner type: " << d_precond_type << std::endl); } HYPRE_StructBiCGSTABSetup(d_solver,d_matrix, d_rhs_vec, d_sol_vec); } else { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " unknown solver type: " << d_solver_type << std::endl); } return; }// setupHypreSolver
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; }
int main (int argc, char *argv[]) { int myid, num_procs; HYPRE_SStructGrid grid; HYPRE_SStructGraph graph; HYPRE_SStructStencil stencil; HYPRE_SStructMatrix A; HYPRE_SStructVector b; HYPRE_SStructVector x; /* We are using struct solvers for this example */ HYPRE_StructSolver solver; HYPRE_StructSolver precond; int object_type; /* Initialize MPI */ MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myid); MPI_Comm_size(MPI_COMM_WORLD, &num_procs); if (num_procs != 2) { if (myid ==0) printf("Must run with 2 processors!\n"); MPI_Finalize(); return(0); } /* 1. Set up the 2D grid. This gives the index space in each part. Here we only use one part and one variable. (So the part id is 0 and the variable id is 0) */ { int ndim = 2; int nparts = 1; int part = 0; /* Create an empty 2D grid object */ HYPRE_SStructGridCreate(MPI_COMM_WORLD, ndim, nparts, &grid); /* Set the extents of the grid - each processor sets its grid boxes. Each part has its own relative index space numbering, but in this example all boxes belong to the same part. */ /* Processor 0 owns two boxes in the grid. */ if (myid == 0) { /* Add a new box to the grid */ { int ilower[2] = {-3, 1}; int iupper[2] = {-1, 2}; HYPRE_SStructGridSetExtents(grid, part, ilower, iupper); } /* Add a new box to the grid */ { int ilower[2] = {0, 1}; int iupper[2] = {2, 4}; HYPRE_SStructGridSetExtents(grid, part, ilower, iupper); } } /* Processor 1 owns one box in the grid. */ else if (myid == 1) { /* Add a new box to the grid */ { int ilower[2] = {3, 1}; int iupper[2] = {6, 4}; HYPRE_SStructGridSetExtents(grid, part, ilower, iupper); } } /* Set the variable type and number of variables on each part. */ { int i; int nvars = 1; HYPRE_SStructVariable vartypes[1] = {HYPRE_SSTRUCT_VARIABLE_CELL}; for (i = 0; i< nparts; i++) HYPRE_SStructGridSetVariables(grid, i, nvars, vartypes); } /* Now the grid is ready to use */ HYPRE_SStructGridAssemble(grid); } /* 2. Define the discretization stencil(s) */ { /* Create an empty 2D, 5-pt stencil object */ HYPRE_SStructStencilCreate(2, 5, &stencil); /* Define the geometry of the stencil. Each represents a relative offset (in the index space). */ { int entry; int offsets[5][2] = {{0,0}, {-1,0}, {1,0}, {0,-1}, {0,1}}; int var = 0; /* Assign numerical values to the offsets so that we can easily refer to them - the last argument indicates the variable for which we are assigning this stencil - we are just using one variable in this example so it is the first one (0) */ for (entry = 0; entry < 5; entry++) HYPRE_SStructStencilSetEntry(stencil, entry, offsets[entry], var); } } /* 3. Set up the Graph - this determines the non-zero structure of the matrix and allows non-stencil relationships between the parts */ { int var = 0; int part = 0; /* Create the graph object */ HYPRE_SStructGraphCreate(MPI_COMM_WORLD, grid, &graph); /* See MatrixSetObjectType below */ object_type = HYPRE_STRUCT; HYPRE_SStructGraphSetObjectType(graph, object_type); /* Now we need to tell the graph which stencil to use for each variable on each part (we only have one variable and one part) */ HYPRE_SStructGraphSetStencil(graph, part, var, stencil); /* Here we could establish connections between parts if we had more than one part using the graph. For example, we could use HYPRE_GraphAddEntries() routine or HYPRE_GridSetNeighborBox() */ /* Assemble the graph */ HYPRE_SStructGraphAssemble(graph); } /* 4. Set up a SStruct Matrix */ { int i,j; int part = 0; int var = 0; /* Create the empty matrix object */ HYPRE_SStructMatrixCreate(MPI_COMM_WORLD, graph, &A); /* Set the object type (by default HYPRE_SSTRUCT). This determines the data structure used to store the matrix. If you want to use unstructured solvers, e.g. BoomerAMG, the object type should be HYPRE_PARCSR. If the problem is purely structured (with one part), you may want to use HYPRE_STRUCT to access the structured solvers. Here we have a purely structured example. */ object_type = HYPRE_STRUCT; HYPRE_SStructMatrixSetObjectType(A, object_type); /* Get ready to set values */ HYPRE_SStructMatrixInitialize(A); /* Each processor must set the stencil values for their boxes on each part. In this example, we only set stencil entries and therefore use HYPRE_SStructMatrixSetBoxValues. If we need to set non-stencil entries, we have to use HYPRE_SStructMatrixSetValues (shown in a later example). */ if (myid == 0) { /* Set the matrix coefficients for some set of stencil entries over all the gridpoints in my first box (account for boundary grid points later) */ { int ilower[2] = {-3, 1}; int iupper[2] = {-1, 2}; int nentries = 5; int nvalues = 30; /* 6 grid points, each with 5 stencil entries */ double values[30]; int stencil_indices[5]; for (j = 0; j < nentries; j++) /* label the stencil indices - these correspond to the offsets defined above */ stencil_indices[j] = j; for (i = 0; i < nvalues; i += nentries) { values[i] = 4.0; for (j = 1; j < nentries; j++) values[i+j] = -1.0; } HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, nentries, stencil_indices, values); } /* Set the matrix coefficients for some set of stencil entries over the gridpoints in my second box */ { int ilower[2] = {0, 1}; int iupper[2] = {2, 4}; int nentries = 5; int nvalues = 60; /* 12 grid points, each with 5 stencil entries */ double values[60]; int stencil_indices[5]; for (j = 0; j < nentries; j++) stencil_indices[j] = j; for (i = 0; i < nvalues; i += nentries) { values[i] = 4.0; for (j = 1; j < nentries; j++) values[i+j] = -1.0; } HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, nentries, stencil_indices, values); } } else if (myid == 1) { /* Set the matrix coefficients for some set of stencil entries over the gridpoints in my box */ { int ilower[2] = {3, 1}; int iupper[2] = {6, 4}; int nentries = 5; int nvalues = 80; /* 16 grid points, each with 5 stencil entries */ double values[80]; int stencil_indices[5]; for (j = 0; j < nentries; j++) stencil_indices[j] = j; for (i = 0; i < nvalues; i += nentries) { values[i] = 4.0; for (j = 1; j < nentries; j++) values[i+j] = -1.0; } HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, nentries, stencil_indices, values); } } /* For each box, set any coefficients that reach ouside of the boundary to 0 */ if (myid == 0) { int maxnvalues = 6; double values[6]; for (i = 0; i < maxnvalues; i++) values[i] = 0.0; { /* Values below our first AND second box */ int ilower[2] = {-3, 1}; int iupper[2] = { 2, 1}; int stencil_indices[1] = {3}; HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, 1, stencil_indices, values); } { /* Values to the left of our first box */ int ilower[2] = {-3, 1}; int iupper[2] = {-3, 2}; int stencil_indices[1] = {1}; HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, 1, stencil_indices, values); } { /* Values above our first box */ int ilower[2] = {-3, 2}; int iupper[2] = {-1, 2}; int stencil_indices[1] = {4}; HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, 1, stencil_indices, values); } { /* Values to the left of our second box (that do not border the first box). */ int ilower[2] = { 0, 3}; int iupper[2] = { 0, 4}; int stencil_indices[1] = {1}; HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, 1, stencil_indices, values); } { /* Values above our second box */ int ilower[2] = { 0, 4}; int iupper[2] = { 2, 4}; int stencil_indices[1] = {4}; HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, 1, stencil_indices, values); } } else if (myid == 1) { int maxnvalues = 4; double values[4]; for (i = 0; i < maxnvalues; i++) values[i] = 0.0; { /* Values below our box */ int ilower[2] = { 3, 1}; int iupper[2] = { 6, 1}; int stencil_indices[1] = {3}; HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, 1, stencil_indices, values); } { /* Values to the right of our box */ int ilower[2] = { 6, 1}; int iupper[2] = { 6, 4}; int stencil_indices[1] = {2}; HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, 1, stencil_indices, values); } { /* Values above our box */ int ilower[2] = { 3, 4}; int iupper[2] = { 6, 4}; int stencil_indices[1] = {4}; HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, 1, stencil_indices, values); } } /* This is a collective call finalizing the matrix assembly. The matrix is now ``ready to be used'' */ HYPRE_SStructMatrixAssemble(A); } /* 5. Set up SStruct Vectors for b and x */ { int i; /* We have one part and one variable. */ int part = 0; int var = 0; /* Create an empty vector object */ HYPRE_SStructVectorCreate(MPI_COMM_WORLD, grid, &b); HYPRE_SStructVectorCreate(MPI_COMM_WORLD, grid, &x); /* As with the matrix, set the object type for the vectors to be the struct type */ object_type = HYPRE_STRUCT; HYPRE_SStructVectorSetObjectType(b, object_type); HYPRE_SStructVectorSetObjectType(x, object_type); /* Indicate that the vector coefficients are ready to be set */ HYPRE_SStructVectorInitialize(b); HYPRE_SStructVectorInitialize(x); if (myid == 0) { /* Set the vector coefficients over the gridpoints in my first box */ { int ilower[2] = {-3, 1}; int iupper[2] = {-1, 2}; int nvalues = 6; /* 6 grid points */ double values[6]; for (i = 0; i < nvalues; i ++) values[i] = 1.0; HYPRE_SStructVectorSetBoxValues(b, part, ilower, iupper, var, values); for (i = 0; i < nvalues; i ++) values[i] = 0.0; HYPRE_SStructVectorSetBoxValues(x, part, ilower, iupper, var, values); } /* Set the vector coefficients over the gridpoints in my second box */ { int ilower[2] = { 0, 1}; int iupper[2] = { 2, 4}; int nvalues = 12; /* 12 grid points */ double values[12]; for (i = 0; i < nvalues; i ++) values[i] = 1.0; HYPRE_SStructVectorSetBoxValues(b, part, ilower, iupper, var, values); for (i = 0; i < nvalues; i ++) values[i] = 0.0; HYPRE_SStructVectorSetBoxValues(x, part, ilower, iupper, var, values); } } else if (myid == 1) { /* Set the vector coefficients over the gridpoints in my box */ { int ilower[2] = { 3, 1}; int iupper[2] = { 6, 4}; int nvalues = 16; /* 16 grid points */ double values[16]; for (i = 0; i < nvalues; i ++) values[i] = 1.0; HYPRE_SStructVectorSetBoxValues(b, part, ilower, iupper, var, values); for (i = 0; i < nvalues; i ++) values[i] = 0.0; HYPRE_SStructVectorSetBoxValues(x, part, ilower, iupper, var, values); } } /* This is a collective call finalizing the vector assembly. The vectors are now ``ready to be used'' */ HYPRE_SStructVectorAssemble(b); HYPRE_SStructVectorAssemble(x); } /* 6. Set up and use a solver (See the Reference Manual for descriptions of all of the options.) */ { HYPRE_StructMatrix sA; HYPRE_StructVector sb; HYPRE_StructVector sx; /* Because we are using a struct solver, we need to get the object of the matrix and vectors to pass in to the struct solvers */ HYPRE_SStructMatrixGetObject(A, (void **) &sA); HYPRE_SStructVectorGetObject(b, (void **) &sb); HYPRE_SStructVectorGetObject(x, (void **) &sx); /* Create an empty PCG Struct solver */ HYPRE_StructPCGCreate(MPI_COMM_WORLD, &solver); /* Set PCG parameters */ HYPRE_StructPCGSetTol(solver, 1.0e-06); HYPRE_StructPCGSetPrintLevel(solver, 2); HYPRE_StructPCGSetMaxIter(solver, 50); /* Create the Struct SMG solver for use as a preconditioner */ HYPRE_StructSMGCreate(MPI_COMM_WORLD, &precond); /* Set SMG parameters */ HYPRE_StructSMGSetMaxIter(precond, 1); HYPRE_StructSMGSetTol(precond, 0.0); HYPRE_StructSMGSetZeroGuess(precond); HYPRE_StructSMGSetNumPreRelax(precond, 1); HYPRE_StructSMGSetNumPostRelax(precond, 1); /* Set preconditioner and solve */ HYPRE_StructPCGSetPrecond(solver, HYPRE_StructSMGSolve, HYPRE_StructSMGSetup, precond); HYPRE_StructPCGSetup(solver, sA, sb, sx); HYPRE_StructPCGSolve(solver, sA, sb, sx); } /* Free memory */ HYPRE_SStructGridDestroy(grid); HYPRE_SStructStencilDestroy(stencil); HYPRE_SStructGraphDestroy(graph); HYPRE_SStructMatrixDestroy(A); HYPRE_SStructVectorDestroy(b); HYPRE_SStructVectorDestroy(x); HYPRE_StructPCGDestroy(solver); HYPRE_StructSMGDestroy(precond); /* Finalize MPI */ MPI_Finalize(); return (0); }
int main (int argc, char *argv[]) { int i, j; int myid, num_procs; HYPRE_StructGrid grid; HYPRE_StructStencil stencil; HYPRE_StructMatrix A; HYPRE_StructVector b; HYPRE_StructVector x; HYPRE_StructSolver solver; HYPRE_StructSolver precond; /* Initialize MPI */ MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myid); MPI_Comm_size(MPI_COMM_WORLD, &num_procs); if (num_procs != 2) { if (myid ==0) printf("Must run with 2 processors!\n"); MPI_Finalize(); return(0); } /* 1. Set up a grid */ { /* Create an empty 2D grid object */ HYPRE_StructGridCreate(MPI_COMM_WORLD, 2, &grid); /* Processor 0 owns two boxes in the grid. */ if (myid == 0) { /* Add a new box to the grid */ { int ilower[2] = {-3, 1}; int iupper[2] = {-1, 2}; HYPRE_StructGridSetExtents(grid, ilower, iupper); } /* Add a new box to the grid */ { int ilower[2] = {0, 1}; int iupper[2] = {2, 4}; HYPRE_StructGridSetExtents(grid, ilower, iupper); } } /* Processor 1 owns one box in the grid. */ else if (myid == 1) { /* Add a new box to the grid */ { int ilower[2] = {3, 1}; int iupper[2] = {6, 4}; HYPRE_StructGridSetExtents(grid, ilower, iupper); } } /* This is a collective call finalizing the grid assembly. The grid is now ``ready to be used'' */ HYPRE_StructGridAssemble(grid); } /* 2. Define the discretization stencil */ { /* Create an empty 2D, 5-pt stencil object */ HYPRE_StructStencilCreate(2, 5, &stencil); /* Define the geometry of the stencil. Each represents a relative offset (in the index space). */ { int entry; int offsets[5][2] = {{0,0}, {-1,0}, {1,0}, {0,-1}, {0,1}}; /* Assign each of the 5 stencil entries */ for (entry = 0; entry < 5; entry++) HYPRE_StructStencilSetElement(stencil, entry, offsets[entry]); } } /* 3. Set up a Struct Matrix */ { /* Create an empty matrix object */ HYPRE_StructMatrixCreate(MPI_COMM_WORLD, grid, stencil, &A); /* Indicate that the matrix coefficients are ready to be set */ HYPRE_StructMatrixInitialize(A); if (myid == 0) { /* Set the matrix coefficients for some set of stencil entries over all the gridpoints in my first box (account for boundary grid points later) */ { int ilower[2] = {-3, 1}; int iupper[2] = {-1, 2}; int nentries = 5; int nvalues = 30; /* 6 grid points, each with 5 stencil entries */ double values[30]; int stencil_indices[5]; for (j = 0; j < nentries; j++) /* label the stencil indices - these correspond to the offsets defined above */ stencil_indices[j] = j; for (i = 0; i < nvalues; i += nentries) { values[i] = 4.0; for (j = 1; j < nentries; j++) values[i+j] = -1.0; } HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, nentries, stencil_indices, values); } /* Set the matrix coefficients for some set of stencil entries over the gridpoints in my second box */ { int ilower[2] = {0, 1}; int iupper[2] = {2, 4}; int nentries = 5; int nvalues = 60; /* 12 grid points, each with 5 stencil entries */ double values[60]; int stencil_indices[5]; for (j = 0; j < nentries; j++) stencil_indices[j] = j; for (i = 0; i < nvalues; i += nentries) { values[i] = 4.0; for (j = 1; j < nentries; j++) values[i+j] = -1.0; } HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, nentries, stencil_indices, values); } } else if (myid == 1) { /* Set the matrix coefficients for some set of stencil entries over the gridpoints in my box */ { int ilower[2] = {3, 1}; int iupper[2] = {6, 4}; int nentries = 5; int nvalues = 80; /* 16 grid points, each with 5 stencil entries */ double values[80]; int stencil_indices[5]; for (j = 0; j < nentries; j++) stencil_indices[j] = j; for (i = 0; i < nvalues; i += nentries) { values[i] = 4.0; for (j = 1; j < nentries; j++) values[i+j] = -1.0; } HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, nentries, stencil_indices, values); } } /* For each box, set any coefficients that reach ouside of the boundary to 0 */ if (myid == 0) { int maxnvalues = 6; double values[6]; for (i = 0; i < maxnvalues; i++) values[i] = 0.0; { /* Values below our first AND second box */ int ilower[2] = {-3, 1}; int iupper[2] = { 2, 1}; int stencil_indices[1] = {3}; HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, 1, stencil_indices, values); } { /* Values to the left of our first box */ int ilower[2] = {-3, 1}; int iupper[2] = {-3, 2}; int stencil_indices[1] = {1}; HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, 1, stencil_indices, values); } { /* Values above our first box */ int ilower[2] = {-3, 2}; int iupper[2] = {-1, 2}; int stencil_indices[1] = {4}; HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, 1, stencil_indices, values); } { /* Values to the left of our second box (that do not border the first box). */ int ilower[2] = { 0, 3}; int iupper[2] = { 0, 4}; int stencil_indices[1] = {1}; HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, 1, stencil_indices, values); } { /* Values above our second box */ int ilower[2] = { 0, 4}; int iupper[2] = { 2, 4}; int stencil_indices[1] = {4}; HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, 1, stencil_indices, values); } } else if (myid == 1) { int maxnvalues = 4; double values[4]; for (i = 0; i < maxnvalues; i++) values[i] = 0.0; { /* Values below our box */ int ilower[2] = { 3, 1}; int iupper[2] = { 6, 1}; int stencil_indices[1] = {3}; HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, 1, stencil_indices, values); } { /* Values to the right of our box */ int ilower[2] = { 6, 1}; int iupper[2] = { 6, 4}; int stencil_indices[1] = {2}; HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, 1, stencil_indices, values); } { /* Values above our box */ int ilower[2] = { 3, 4}; int iupper[2] = { 6, 4}; int stencil_indices[1] = {4}; HYPRE_StructMatrixSetBoxValues(A, ilower, iupper, 1, stencil_indices, values); } } /* This is a collective call finalizing the matrix assembly. The matrix is now ``ready to be used'' */ HYPRE_StructMatrixAssemble(A); } /* 4. Set up Struct Vectors for b and x */ { /* Create an empty vector object */ HYPRE_StructVectorCreate(MPI_COMM_WORLD, grid, &b); HYPRE_StructVectorCreate(MPI_COMM_WORLD, grid, &x); /* Indicate that the vector coefficients are ready to be set */ HYPRE_StructVectorInitialize(b); HYPRE_StructVectorInitialize(x); if (myid == 0) { /* Set the vector coefficients over the gridpoints in my first box */ { int ilower[2] = {-3, 1}; int iupper[2] = {-1, 2}; int nvalues = 6; /* 6 grid points */ double values[6]; for (i = 0; i < nvalues; i ++) values[i] = 1.0; HYPRE_StructVectorSetBoxValues(b, ilower, iupper, values); for (i = 0; i < nvalues; i ++) values[i] = 0.0; HYPRE_StructVectorSetBoxValues(x, ilower, iupper, values); } /* Set the vector coefficients over the gridpoints in my second box */ { int ilower[2] = { 0, 1}; int iupper[2] = { 2, 4}; int nvalues = 12; /* 12 grid points */ double values[12]; for (i = 0; i < nvalues; i ++) values[i] = 1.0; HYPRE_StructVectorSetBoxValues(b, ilower, iupper, values); for (i = 0; i < nvalues; i ++) values[i] = 0.0; HYPRE_StructVectorSetBoxValues(x, ilower, iupper, values); } } else if (myid == 1) { /* Set the vector coefficients over the gridpoints in my box */ { int ilower[2] = { 3, 1}; int iupper[2] = { 6, 4}; int nvalues = 16; /* 16 grid points */ double values[16]; for (i = 0; i < nvalues; i ++) values[i] = 1.0; HYPRE_StructVectorSetBoxValues(b, ilower, iupper, values); for (i = 0; i < nvalues; i ++) values[i] = 0.0; HYPRE_StructVectorSetBoxValues(x, ilower, iupper, values); } } /* This is a collective call finalizing the vector assembly. The vectors are now ``ready to be used'' */ HYPRE_StructVectorAssemble(b); HYPRE_StructVectorAssemble(x); } /* 5. Set up and use a solver (See the Reference Manual for descriptions of all of the options.) */ { /* Create an empty PCG Struct solver */ HYPRE_StructPCGCreate(MPI_COMM_WORLD, &solver); /* Set PCG parameters */ HYPRE_StructPCGSetTol(solver, 1.0e-06); HYPRE_StructPCGSetPrintLevel(solver, 2); HYPRE_StructPCGSetMaxIter(solver, 50); /* Use symmetric SMG as preconditioner */ HYPRE_StructSMGCreate(MPI_COMM_WORLD, &precond); HYPRE_StructSMGSetMaxIter(precond, 1); HYPRE_StructSMGSetTol(precond, 0.0); HYPRE_StructSMGSetZeroGuess(precond); HYPRE_StructSMGSetNumPreRelax(precond, 1); HYPRE_StructSMGSetNumPostRelax(precond, 1); /* Set preconditioner and solve */ HYPRE_StructPCGSetPrecond(solver, HYPRE_StructSMGSolve, HYPRE_StructSMGSetup, precond); HYPRE_StructPCGSetup(solver, A, b, x); HYPRE_StructPCGSolve(solver, A, b, x); } /* Free memory */ HYPRE_StructGridDestroy(grid); HYPRE_StructStencilDestroy(stencil); HYPRE_StructMatrixDestroy(A); HYPRE_StructVectorDestroy(b); HYPRE_StructVectorDestroy(x); HYPRE_StructPCGDestroy(solver); HYPRE_StructSMGDestroy(precond); /* Finalize MPI */ MPI_Finalize(); return (0); }