예제 #1
0
HYPRE_Int
hypre_SStructPMatvecCompute( void                 *pmatvec_vdata,
                             HYPRE_Complex         alpha,
                             hypre_SStructPMatrix *pA,
                             hypre_SStructPVector *px,
                             HYPRE_Complex         beta,
                             hypre_SStructPVector *py )
{
   hypre_SStructPMatvecData   *pmatvec_data = pmatvec_vdata;
   HYPRE_Int                   nvars        = (pmatvec_data -> nvars);
   void                     ***smatvec_data = (pmatvec_data -> smatvec_data);

   void                       *sdata;
   hypre_StructMatrix         *sA;
   hypre_StructVector         *sx;
   hypre_StructVector         *sy;

   HYPRE_Int                  vi, vj;

   for (vi = 0; vi < nvars; vi++)
   {
      sy = hypre_SStructPVectorSVector(py, vi);

      /* diagonal block computation */
      if (smatvec_data[vi][vi] != NULL)
      {
         sdata = smatvec_data[vi][vi];
         sA = hypre_SStructPMatrixSMatrix(pA, vi, vi);
         sx = hypre_SStructPVectorSVector(px, vi);
         hypre_StructMatvecCompute(sdata, alpha, sA, sx, beta, sy);
      }
      else
      {
         hypre_StructScale(beta, sy);
      }

      /* off-diagonal block computation */
      for (vj = 0; vj < nvars; vj++)
      {
         if ((smatvec_data[vi][vj] != NULL) && (vj != vi))
         {
            sdata = smatvec_data[vi][vj];
            sA = hypre_SStructPMatrixSMatrix(pA, vi, vj);
            sx = hypre_SStructPVectorSVector(px, vj);
            hypre_StructMatvecCompute(sdata, alpha, sA, sx, 1.0, sy);
         }
      }
   }

   return hypre_error_flag;
}
예제 #2
0
파일: sstruct_matrix.c 프로젝트: 8l/insieme
int
hypre_SStructPMatrixPrint( const char           *filename,
                           hypre_SStructPMatrix *pmatrix,
                           int                   all )
{
    int                 nvars = hypre_SStructPMatrixNVars(pmatrix);
    hypre_StructMatrix *smatrix;
    int                 vi, vj;
    char                new_filename[255];

    for (vi = 0; vi < nvars; vi++)
    {
        for (vj = 0; vj < nvars; vj++)
        {
            smatrix = hypre_SStructPMatrixSMatrix(pmatrix, vi, vj);
            if (smatrix != NULL)
            {
                sprintf(new_filename, "%s.%02d.%02d", filename, vi, vj);
                hypre_StructMatrixPrint(new_filename, smatrix, all);
            }
        }
    }

    return hypre_error_flag;
}
예제 #3
0
파일: sstruct_matrix.c 프로젝트: 8l/insieme
int
hypre_SStructPMatrixSetValues( hypre_SStructPMatrix *pmatrix,
                               hypre_Index           index,
                               int                   var,
                               int                   nentries,
                               int                  *entries,
                               double               *values,
                               int                   add_to )
{
    hypre_SStructStencil *stencil = hypre_SStructPMatrixStencil(pmatrix, var);
    int                  *smap    = hypre_SStructPMatrixSMap(pmatrix, var);
    int                  *vars    = hypre_SStructStencilVars(stencil);
    hypre_StructMatrix   *smatrix;
    int                  *sentries;
    int                   i;

    smatrix = hypre_SStructPMatrixSMatrix(pmatrix, var, vars[entries[0]]);

    sentries = hypre_SStructPMatrixSEntries(pmatrix);
    for (i = 0; i < nentries; i++)
    {
        sentries[i] = smap[entries[i]];
    }

    hypre_StructMatrixSetValues(smatrix, index, nentries, sentries, values, add_to);

    return hypre_error_flag;
}
예제 #4
0
HYPRE_Int
hypre_SStructPMatvecSetup( void                 *pmatvec_vdata,
                           hypre_SStructPMatrix *pA,
                           hypre_SStructPVector *px )
{
   hypre_SStructPMatvecData   *pmatvec_data = pmatvec_vdata;
   HYPRE_Int                   nvars;
   void                     ***smatvec_data;
   hypre_StructMatrix         *sA;
   hypre_StructVector         *sx;
   HYPRE_Int                   vi, vj;

   nvars = hypre_SStructPMatrixNVars(pA);
   smatvec_data = hypre_TAlloc(void **, nvars);
   for (vi = 0; vi < nvars; vi++)
   {
      smatvec_data[vi] = hypre_TAlloc(void *, nvars);
      for (vj = 0; vj < nvars; vj++)
      {
         sA = hypre_SStructPMatrixSMatrix(pA, vi, vj);
         sx = hypre_SStructPVectorSVector(px, vj);
         smatvec_data[vi][vj] = NULL;
         if (sA != NULL)
         {
            smatvec_data[vi][vj] = hypre_StructMatvecCreate();
            hypre_StructMatvecSetup(smatvec_data[vi][vj], sA, sx);
         }
      }
   }
   (pmatvec_data -> nvars)        = nvars;
   (pmatvec_data -> smatvec_data) = smatvec_data;

   return hypre_error_flag;
}
예제 #5
0
HYPRE_Int
hypre_SysPFMGSetupRAPOp( hypre_SStructPMatrix *R,
                         hypre_SStructPMatrix *A,
                         hypre_SStructPMatrix *P,
                         HYPRE_Int             cdir,
                         hypre_Index           cindex,
                         hypre_Index           cstride,
                         hypre_SStructPMatrix *Ac      )
{
    HYPRE_Int               nvars;
    HYPRE_Int               vi,vj;

    hypre_StructMatrix    *R_s;
    hypre_StructMatrix    *A_s;
    hypre_StructMatrix    *P_s;

    hypre_StructMatrix    *Ac_s;

    HYPRE_Int              P_stored_as_transpose = 0;

    nvars = hypre_SStructPMatrixNVars(A);

    /*--------------------------------------------------------------------------
     * Symmetry within a block is exploited, but not symmetry of the form
     * A_{vi,vj} = A_{vj,vi}^T.
     *--------------------------------------------------------------------------*/

    for (vi = 0; vi < nvars; vi++)
    {
        R_s = hypre_SStructPMatrixSMatrix(R, vi, vi);
        for (vj = 0; vj < nvars; vj++)
        {
            A_s  = hypre_SStructPMatrixSMatrix(A, vi, vj);
            Ac_s = hypre_SStructPMatrixSMatrix(Ac, vi, vj);
            P_s  = hypre_SStructPMatrixSMatrix(P, vj, vj);
            if (A_s != NULL)
            {
                hypre_SemiBuildRAP(A_s, P_s, R_s, cdir, cindex, cstride,
                                   P_stored_as_transpose, Ac_s);
                /* Assemble here? */
                hypre_StructMatrixAssemble(Ac_s);
            }
        }
    }

    return hypre_error_flag;
}
예제 #6
0
HYPRE_Int
hypre_SysPFMGSetupInterpOp( hypre_SStructPMatrix *A,
                            HYPRE_Int             cdir,
                            hypre_Index           findex,
                            hypre_Index           stride,
                            hypre_SStructPMatrix *P      )
{
   HYPRE_Int              nvars;
   hypre_StructMatrix    *A_s;
   hypre_StructMatrix    *P_s;
   HYPRE_Int              vi;

   nvars = hypre_SStructPMatrixNVars(A);

   for (vi = 0; vi < nvars; vi++)
   {
      A_s = hypre_SStructPMatrixSMatrix(A, vi, vi);
      P_s = hypre_SStructPMatrixSMatrix(P, vi, vi);
      hypre_PFMGSetupInterpOp(A_s, cdir, findex, stride, P_s, 0);
   }

   return hypre_error_flag;
}
예제 #7
0
파일: sstruct_matrix.c 프로젝트: 8l/insieme
/*--------------------------------------------------------------------------
 * hypre_SStructPMatrixInitialize
 *--------------------------------------------------------------------------*/
int
hypre_SStructPMatrixInitialize( hypre_SStructPMatrix *pmatrix )
{
    int                    nvars       = hypre_SStructPMatrixNVars(pmatrix);
    int                  **symmetric   = hypre_SStructPMatrixSymmetric(pmatrix);
    hypre_SStructPGrid    *pgrid       = hypre_SStructPMatrixPGrid(pmatrix);
    HYPRE_SStructVariable *vartypes    = hypre_SStructPGridVarTypes(pgrid);
    int                    ndim        = hypre_SStructPGridNDim(pgrid);

    int                    num_ghost[6]= {1, 1, 1, 1, 1, 1};
    hypre_StructMatrix    *smatrix;
    hypre_StructGrid      *sgrid;

    hypre_Index            varoffset;
    int                    vi, vj, d;

    for (vi = 0; vi < nvars; vi++)
    {
        /* use variable vi add_numghost */
        sgrid= hypre_SStructPGridSGrid(pgrid, vi);
        hypre_SStructVariableGetOffset(vartypes[vi], ndim, varoffset);

        for (vj = 0; vj < nvars; vj++)
        {
            smatrix = hypre_SStructPMatrixSMatrix(pmatrix, vi, vj);
            if (smatrix != NULL)
            {
                HYPRE_StructMatrixSetSymmetric(smatrix, symmetric[vi][vj]);
                hypre_StructMatrixSetNumGhost(smatrix, num_ghost);

                for (d = 0; d < 3; d++)
                {
                    hypre_StructMatrixAddNumGhost(smatrix)[2*d]=
                        hypre_IndexD(varoffset, d);
                    hypre_StructMatrixAddNumGhost(smatrix)[2*d+1]=
                        hypre_IndexD(varoffset, d);
                }

                hypre_StructMatrixInitialize(smatrix);
            }
        }
    }

    return hypre_error_flag;
}
예제 #8
0
파일: sstruct_matrix.c 프로젝트: 8l/insieme
int
hypre_SStructPMatrixAssemble( hypre_SStructPMatrix *pmatrix )
{
    int                 nvars = hypre_SStructPMatrixNVars(pmatrix);
    hypre_StructMatrix *smatrix;
    int                 vi, vj;

    for (vi = 0; vi < nvars; vi++)
    {
        for (vj = 0; vj < nvars; vj++)
        {
            smatrix = hypre_SStructPMatrixSMatrix(pmatrix, vi, vj);
            if (smatrix != NULL)
            {
                hypre_StructMatrixAssemble(smatrix);
            }
        }
    }

    return hypre_error_flag;
}
예제 #9
0
파일: sstruct_matrix.c 프로젝트: 8l/insieme
int
hypre_SStructPMatrixSetBoxValues( hypre_SStructPMatrix *pmatrix,
                                  hypre_Index           ilower,
                                  hypre_Index           iupper,
                                  int                   var,
                                  int                   nentries,
                                  int                  *entries,
                                  double               *values,
                                  int                   add_to )
{
    hypre_SStructStencil *stencil = hypre_SStructPMatrixStencil(pmatrix, var);
    int                  *smap    = hypre_SStructPMatrixSMap(pmatrix, var);
    int                  *vars    = hypre_SStructStencilVars(stencil);
    hypre_StructMatrix   *smatrix;
    hypre_Box            *box;
    int                  *sentries;
    int                   i;

    smatrix = hypre_SStructPMatrixSMatrix(pmatrix, var, vars[entries[0]]);

    box = hypre_BoxCreate();
    hypre_CopyIndex(ilower, hypre_BoxIMin(box));
    hypre_CopyIndex(iupper, hypre_BoxIMax(box));

    sentries = hypre_SStructPMatrixSEntries(pmatrix);
    for (i = 0; i < nentries; i++)
    {
        sentries[i] = smap[entries[i]];
    }

    hypre_StructMatrixSetBoxValues(smatrix, box, nentries, sentries, values, add_to);

    hypre_BoxDestroy(box);

    return hypre_error_flag;
}
예제 #10
0
hypre_SStructPMatrix *
hypre_SysPFMGCreateRAPOp( hypre_SStructPMatrix *R,
                          hypre_SStructPMatrix *A,
                          hypre_SStructPMatrix *P,
                          hypre_SStructPGrid   *coarse_grid,
                          HYPRE_Int             cdir        )
{
    hypre_SStructPMatrix    *RAP;
    HYPRE_Int                ndim;
    HYPRE_Int                nvars;
    hypre_SStructVariable    vartype;

    hypre_SStructStencil **RAP_stencils;

    hypre_StructMatrix    *RAP_s;
    hypre_StructMatrix    *R_s;
    hypre_StructMatrix    *A_s;
    hypre_StructMatrix    *P_s;

    hypre_Index          **RAP_shapes;

    hypre_StructStencil   *sstencil;
    hypre_Index           *shape;
    HYPRE_Int              s;
    HYPRE_Int             *sstencil_sizes;

    HYPRE_Int              stencil_size;

    hypre_StructGrid      *cgrid;

    HYPRE_Int              vi,vj;

    HYPRE_Int              sten_cntr;

    HYPRE_Int              P_stored_as_transpose = 0;

    ndim = hypre_StructStencilDim(hypre_SStructPMatrixSStencil(A, 0, 0));
    nvars = hypre_SStructPMatrixNVars(A);

    vartype = hypre_SStructPGridVarType(coarse_grid, 0);
    cgrid = hypre_SStructPGridVTSGrid(coarse_grid, vartype);

    RAP_stencils = hypre_CTAlloc(hypre_SStructStencil *, nvars);

    RAP_shapes = hypre_CTAlloc(hypre_Index *, nvars);
    sstencil_sizes = hypre_CTAlloc(HYPRE_Int, nvars);

    /*--------------------------------------------------------------------------
     * Symmetry within a block is exploited, but not symmetry of the form
     * A_{vi,vj} = A_{vj,vi}^T.
     *--------------------------------------------------------------------------*/

    for (vi = 0; vi < nvars; vi++)
    {
        R_s = hypre_SStructPMatrixSMatrix(R, vi, vi);
        stencil_size = 0;
        for (vj = 0; vj < nvars; vj++)
        {
            A_s = hypre_SStructPMatrixSMatrix(A, vi, vj);
            P_s = hypre_SStructPMatrixSMatrix(P, vj, vj);
            sstencil_sizes[vj] = 0;
            if (A_s != NULL)
            {
                RAP_s = hypre_SemiCreateRAPOp(R_s, A_s, P_s,
                                              cgrid, cdir,
                                              P_stored_as_transpose);
                /* Just want stencil for RAP */
                hypre_StructMatrixInitializeShell(RAP_s);
                sstencil = hypre_StructMatrixStencil(RAP_s);
                shape = hypre_StructStencilShape(sstencil);
                sstencil_sizes[vj] = hypre_StructStencilSize(sstencil);
                stencil_size += sstencil_sizes[vj];
                RAP_shapes[vj] = hypre_CTAlloc(hypre_Index,
                                               sstencil_sizes[vj]);
                for (s = 0; s < sstencil_sizes[vj]; s++)
                {
                    hypre_CopyIndex(shape[s],RAP_shapes[vj][s]);
                }
                hypre_StructMatrixDestroy(RAP_s);
            }
        }

        HYPRE_SStructStencilCreate(ndim, stencil_size, &RAP_stencils[vi]);
        sten_cntr = 0;
        for (vj = 0; vj < nvars; vj++)
        {
            if (sstencil_sizes[vj] > 0)
            {
                for (s = 0; s < sstencil_sizes[vj]; s++)
                {
                    HYPRE_SStructStencilSetEntry(RAP_stencils[vi],
                                                 sten_cntr, RAP_shapes[vj][s], vj);
                    sten_cntr++;
                }
                hypre_TFree(RAP_shapes[vj]);
            }
        }
    }

    /* create RAP Pmatrix */
    hypre_SStructPMatrixCreate(hypre_SStructPMatrixComm(A),
                               coarse_grid, RAP_stencils, &RAP);

    hypre_TFree(RAP_shapes);
    hypre_TFree(sstencil_sizes);

    return RAP;
}
예제 #11
0
/*--------------------------------------------------------------------------
 * hypre_FacZeroCFSten: Zeroes the coarse stencil coefficients that reach 
 * into an underlying coarsened refinement box.
 * Algo: For each cbox
 *       {
 *          1) refine cbox and expand by one in each direction
 *          2) boxman_intersect with the fboxman 
 *                3) loop over intersection boxes to see if stencil
 *                   reaches over.
 *       }
 *--------------------------------------------------------------------------*/
HYPRE_Int
hypre_FacZeroCFSten( hypre_SStructPMatrix *Af,
                     hypre_SStructPMatrix *Ac,
                     hypre_SStructGrid    *grid,
                     HYPRE_Int             fine_part,
                     hypre_Index           rfactors )
{
   hypre_BoxManager      *fboxman;
   hypre_BoxManEntry    **boxman_entries;
   HYPRE_Int              nboxman_entries;

   hypre_SStructPGrid    *p_cgrid;

   hypre_Box              fgrid_box;
   hypre_StructGrid      *cgrid;
   hypre_BoxArray        *cgrid_boxes;
   hypre_Box             *cgrid_box;
   hypre_Box              scaled_box;

   hypre_Box             *shift_ibox;

   hypre_StructMatrix    *smatrix;

   hypre_StructStencil   *stencils;
   HYPRE_Int              stencil_size;

   hypre_Index            refine_factors, upper_shift;
   hypre_Index            stride;
   hypre_Index            stencil_shape;
   hypre_Index            zero_index, ilower, iupper;

   HYPRE_Int              nvars, var1, var2;
   HYPRE_Int              ndim;

   hypre_Box             *ac_dbox;
   HYPRE_Real            *ac_ptr;
   hypre_Index            loop_size;

   HYPRE_Int              iac;
   HYPRE_Int              ci, i, j;

   HYPRE_Int              abs_shape;

   HYPRE_Int              ierr = 0;

   p_cgrid  = hypre_SStructPMatrixPGrid(Ac);
   nvars    = hypre_SStructPMatrixNVars(Ac);
   ndim     = hypre_SStructPGridNDim(p_cgrid);

   hypre_BoxInit(&fgrid_box, ndim);
   hypre_BoxInit(&scaled_box, ndim);

   hypre_ClearIndex(zero_index);
   hypre_ClearIndex(stride);
   hypre_ClearIndex(upper_shift);
   for (i= 0; i< ndim; i++)
   {
      stride[i]= 1;
      upper_shift[i]= rfactors[i]-1;
   }

   hypre_CopyIndex(rfactors, refine_factors);
   if (ndim < 3)
   {
      for (i= ndim; i< 3; i++)
      {
         refine_factors[i]= 1;
      }
   }
        
   for (var1= 0; var1< nvars; var1++)
   {
      cgrid= hypre_SStructPGridSGrid(hypre_SStructPMatrixPGrid(Ac), var1);
      cgrid_boxes= hypre_StructGridBoxes(cgrid);

      fboxman= hypre_SStructGridBoxManager(grid, fine_part, var1);

      /*------------------------------------------------------------------
       * For each parent coarse box find all fboxes that may be connected
       * through a stencil entry- refine this box, expand it by one
       * in each direction, and boxman_intersect with fboxman
       *------------------------------------------------------------------*/
      hypre_ForBoxI(ci, cgrid_boxes)
      {
         cgrid_box= hypre_BoxArrayBox(cgrid_boxes, ci);

         hypre_StructMapCoarseToFine(hypre_BoxIMin(cgrid_box), zero_index,
                                     refine_factors, hypre_BoxIMin(&scaled_box));
         hypre_StructMapCoarseToFine(hypre_BoxIMax(cgrid_box), upper_shift,
                                     refine_factors, hypre_BoxIMax(&scaled_box));

         hypre_SubtractIndexes(hypre_BoxIMin(&scaled_box), stride, 3,
                               hypre_BoxIMin(&scaled_box));
         hypre_AddIndexes(hypre_BoxIMax(&scaled_box), stride, 3,
                          hypre_BoxIMax(&scaled_box));

         hypre_BoxManIntersect(fboxman, hypre_BoxIMin(&scaled_box),
                               hypre_BoxIMax(&scaled_box), &boxman_entries,
                               &nboxman_entries);

         for (var2= 0; var2< nvars; var2++)
         {
            stencils=  hypre_SStructPMatrixSStencil(Ac, var1, var2);

            if (stencils != NULL)
            {
               stencil_size= hypre_StructStencilSize(stencils);
               smatrix     = hypre_SStructPMatrixSMatrix(Ac, var1, var2);
               ac_dbox     = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(smatrix),
                                               ci);

               /*---------------------------------------------------------
                * Find the stencil coefficients that must be zeroed off.
                * Loop over all possible boxes.
                *---------------------------------------------------------*/
               for (i= 0; i< stencil_size; i++)
               {
                  hypre_CopyIndex(hypre_StructStencilElement(stencils, i),
                                  stencil_shape);
                  AbsStencilShape(stencil_shape, abs_shape);         

                  if (abs_shape)   /* non-centre stencils are zeroed */
                  {
                     /* look for connecting fboxes that must be zeroed. */
                     for (j= 0; j< nboxman_entries; j++)
                     {
                        hypre_BoxManEntryGetExtents(boxman_entries[j], ilower, iupper);
                        hypre_BoxSetExtents(&fgrid_box, ilower, iupper);

                        shift_ibox= hypre_CF_StenBox(&fgrid_box, cgrid_box, stencil_shape, 
                                                     refine_factors, ndim);

                        if ( hypre_BoxVolume(shift_ibox) )
                        {
                           ac_ptr= hypre_StructMatrixExtractPointerByIndex(smatrix,
                                                                           ci,
                                                                           stencil_shape);
                           hypre_BoxGetSize(shift_ibox, loop_size);

                           hypre_BoxLoop1Begin(ndim, loop_size,
                                               ac_dbox, hypre_BoxIMin(shift_ibox),
                                               stride, iac);
#ifdef HYPRE_USING_OPENMP
#pragma omp parallel for private(HYPRE_BOX_PRIVATE,iac) HYPRE_SMP_SCHEDULE
#endif
                           hypre_BoxLoop1For(iac)
                           {
                              ac_ptr[iac] = 0.0;
                           }
                           hypre_BoxLoop1End(iac);
                        }   /* if ( hypre_BoxVolume(shift_ibox) ) */

                        hypre_BoxDestroy(shift_ibox);

                     }  /* for (j= 0; j< nboxman_entries; j++) */
                  }     /* if (abs_shape)  */
               }        /* for (i= 0; i< stencil_size; i++) */
            }           /* if (stencils != NULL) */
         }              /* for (var2= 0; var2< nvars; var2++) */

         hypre_TFree(boxman_entries);
      }   /* hypre_ForBoxI  ci */
예제 #12
0
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;
}
예제 #13
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;
}