void hypre_F90_IFACE(hypre_structsmgsetrelchange, HYPRE_STRUCTSMGSETRELCHANGE) ( hypre_F90_Obj *solver, hypre_F90_Int *rel_change, hypre_F90_Int *ierr ) { *ierr = (hypre_F90_Int) ( HYPRE_StructSMGSetRelChange( hypre_F90_PassObj (HYPRE_StructSolver, solver), hypre_F90_PassInt (rel_change) ) ); }
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