void
hypre_F90_IFACE(hypre_structpfmgsettol, HYPRE_STRUCTPFMGSETTOL)
   ( hypre_F90_Obj *solver,
     hypre_F90_Dbl *tol,
     hypre_F90_Int *ierr   )
{
   *ierr = (hypre_F90_Int)
      ( HYPRE_StructPFMGSetTol(
           hypre_F90_PassObj (HYPRE_StructSolver, solver),
           hypre_F90_PassDbl (tol)    ) );
}
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
bool
CCDivGradHypreLevelSolver::solveSystem(
    const int x_idx,
    const int b_idx,
    const IntVector<NDIM>& chkbrd_mode_id)
{
    Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(d_level_num);

    // Copy solution and right-hand-side data to hypre structures.
    for (PatchLevel<NDIM>::Iterator p(level); p; p++)
    {
        Pointer<Patch<NDIM> > patch = level->getPatch(p());
        const Box<NDIM>& patch_box = patch->getBox();
        Pointer<CellData<NDIM,double> > x_data = patch->getPatchData(x_idx);
        copyToHypre(d_sol_vec, x_data, patch_box, chkbrd_mode_id);
        Pointer<CellData<NDIM,double> > b_data = patch->getPatchData(b_idx);
        copyToHypre(d_rhs_vec, b_data, patch_box, chkbrd_mode_id);
    }

    // Assemble the hypre vectors.
    HYPRE_StructVectorAssemble(d_sol_vec);
    HYPRE_StructVectorAssemble(d_rhs_vec);

    // Solve the system.
    IBTK_TIMER_START(t_solve_system_hypre);

    if (d_solver_type == "PFMG")
    {
        HYPRE_StructPFMGSetMaxIter(d_solver, d_max_iterations);
        HYPRE_StructPFMGSetTol(d_solver, d_rel_residual_tol);
        HYPRE_StructPFMGSolve(d_solver, d_matrix, d_rhs_vec, d_sol_vec);
        HYPRE_StructPFMGGetNumIterations(d_solver, &d_current_its);
        HYPRE_StructPFMGGetFinalRelativeResidualNorm(d_solver, &d_current_residual_norm);
    }
    else if (d_solver_type == "SMG")
    {
        HYPRE_StructSMGSetMaxIter(d_solver, d_max_iterations);
        HYPRE_StructSMGSetTol(d_solver, d_rel_residual_tol);
        HYPRE_StructSMGSolve(d_solver, d_matrix, d_rhs_vec, d_sol_vec);
        HYPRE_StructSMGGetNumIterations(d_solver, &d_current_its);
        HYPRE_StructSMGGetFinalRelativeResidualNorm(d_solver, &d_current_residual_norm);
    }
    else if (d_solver_type == "PCG")
    {
        HYPRE_StructPCGSetMaxIter(d_solver, d_max_iterations);
        HYPRE_StructPCGSetTol(d_solver, d_rel_residual_tol);
        HYPRE_StructPCGSetAbsoluteTol(d_solver, d_abs_residual_tol);
        HYPRE_StructPCGSolve(d_solver, d_matrix, d_rhs_vec, d_sol_vec);
        HYPRE_StructPCGGetNumIterations(d_solver, &d_current_its);
        HYPRE_StructPCGGetFinalRelativeResidualNorm(d_solver, &d_current_residual_norm);
    }
    else if (d_solver_type == "GMRES")
    {
        HYPRE_StructGMRESSetMaxIter(d_solver, d_max_iterations);
        HYPRE_StructGMRESSetTol(d_solver, d_rel_residual_tol);
        HYPRE_StructGMRESSetAbsoluteTol(d_solver, d_abs_residual_tol);
        HYPRE_StructGMRESSolve(d_solver, d_matrix, d_rhs_vec, d_sol_vec);
        HYPRE_StructGMRESGetNumIterations(d_solver, &d_current_its);
        HYPRE_StructGMRESGetFinalRelativeResidualNorm(d_solver, &d_current_residual_norm);
    }
    else if (d_solver_type == "FlexGMRES")
    {
        HYPRE_StructFlexGMRESSetMaxIter(d_solver, d_max_iterations);
        HYPRE_StructFlexGMRESSetTol(d_solver, d_rel_residual_tol);
        HYPRE_StructFlexGMRESSetAbsoluteTol(d_solver, d_abs_residual_tol);
        HYPRE_StructFlexGMRESSolve(d_solver, d_matrix, d_rhs_vec, d_sol_vec);
        HYPRE_StructFlexGMRESGetNumIterations(d_solver, &d_current_its);
        HYPRE_StructFlexGMRESGetFinalRelativeResidualNorm(d_solver, &d_current_residual_norm);
    }
    else if (d_solver_type == "LGMRES")
    {
        HYPRE_StructLGMRESSetMaxIter(d_solver, d_max_iterations);
        HYPRE_StructLGMRESSetTol(d_solver, d_rel_residual_tol);
        HYPRE_StructLGMRESSetAbsoluteTol(d_solver, d_abs_residual_tol);
        HYPRE_StructLGMRESSolve(d_solver, d_matrix, d_rhs_vec, d_sol_vec);
        HYPRE_StructLGMRESGetNumIterations(d_solver, &d_current_its);
        HYPRE_StructLGMRESGetFinalRelativeResidualNorm(d_solver, &d_current_residual_norm);
    }
    else if (d_solver_type == "BiCGSTAB")
    {
        HYPRE_StructBiCGSTABSetMaxIter(d_solver, d_max_iterations);
        HYPRE_StructBiCGSTABSetTol(d_solver, d_rel_residual_tol);
        HYPRE_StructBiCGSTABSetAbsoluteTol(d_solver, d_abs_residual_tol);
        HYPRE_StructBiCGSTABSolve(d_solver, d_matrix, d_rhs_vec, d_sol_vec);
        HYPRE_StructBiCGSTABGetNumIterations(d_solver, &d_current_its);
        HYPRE_StructBiCGSTABGetFinalRelativeResidualNorm(d_solver, &d_current_residual_norm);
    }

    IBTK_TIMER_STOP(t_solve_system_hypre);

    // Pull the solution vector out of the hypre structures.
    for (PatchLevel<NDIM>::Iterator p(level); p; p++)
    {
        Pointer<Patch<NDIM> > patch = level->getPatch(p());
        const Box<NDIM>& patch_box = patch->getBox();
        Pointer<CellData<NDIM,double> > x_data = patch->getPatchData(x_idx);
        copyFromHypre(x_data, d_sol_vec, patch_box, chkbrd_mode_id);
    }
    return (d_current_residual_norm <= d_rel_residual_tol || d_current_residual_norm <= d_abs_residual_tol);
}// solveSystem
Example #4
0
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;
}