Exemple #1
0
int
hypre_SStructPMatrixSetSymmetric( hypre_SStructPMatrix *pmatrix,
                                  int                   var,
                                  int                   to_var,
                                  int                   symmetric )
{
    int **pmsymmetric = hypre_SStructPMatrixSymmetric(pmatrix);

    int vstart = var;
    int vsize  = 1;
    int tstart = to_var;
    int tsize  = 1;
    int v, t;

    if (var == -1)
    {
        vstart = 0;
        vsize  = hypre_SStructPMatrixNVars(pmatrix);
    }
    if (to_var == -1)
    {
        tstart = 0;
        tsize  = hypre_SStructPMatrixNVars(pmatrix);
    }

    for (v = vstart; v < vsize; v++)
    {
        for (t = tstart; t < tsize; t++)
        {
            pmsymmetric[v][t] = symmetric;
        }
    }

    return hypre_error_flag;
}
Exemple #2
0
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;
}
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;
}
hypre_SStructPMatrix *
hypre_SysPFMGCreateInterpOp( hypre_SStructPMatrix *A,
                             hypre_SStructPGrid   *cgrid,
                             HYPRE_Int             cdir  )
{
   hypre_SStructPMatrix  *P;

   hypre_Index           *stencil_shape;
   HYPRE_Int              stencil_size;
                       
   HYPRE_Int              ndim;

   HYPRE_Int              nvars;
   hypre_SStructStencil **P_stencils;

   HYPRE_Int              i,s;

   /* set up stencil_shape */
   stencil_size = 2;
   stencil_shape = hypre_CTAlloc(hypre_Index, stencil_size);
   for (i = 0; i < stencil_size; i++)
   {
      hypre_SetIndex3(stencil_shape[i], 0, 0, 0);
   }
   hypre_IndexD(stencil_shape[0], cdir) = -1;
   hypre_IndexD(stencil_shape[1], cdir) =  1;

   /* set up P_stencils */
   ndim = hypre_StructStencilNDim(hypre_SStructPMatrixSStencil(A, 0, 0));
   nvars = hypre_SStructPMatrixNVars(A);
   P_stencils = hypre_CTAlloc(hypre_SStructStencil *, nvars);
   for (s = 0; s < nvars; s++)
   {
      HYPRE_SStructStencilCreate(ndim, stencil_size, &P_stencils[s]);
      for (i = 0; i < stencil_size; i++)
      {
         HYPRE_SStructStencilSetEntry(P_stencils[s], i,
                                      stencil_shape[i], s);
      }
   }

   /* create interpolation matrix */
   hypre_SStructPMatrixCreate(hypre_SStructPMatrixComm(A), cgrid,
                              P_stencils, &P);

   hypre_TFree(stencil_shape);

   return P;
}
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;
}
Exemple #6
0
int
hypre_SStructPMatrixDestroy( hypre_SStructPMatrix *pmatrix )
{
    hypre_SStructStencil  **stencils;
    int                     nvars;
    int                   **smaps;
    hypre_StructStencil  ***sstencils;
    hypre_StructMatrix   ***smatrices;
    int                   **symmetric;
    int                     vi, vj;

    if (pmatrix)
    {
        hypre_SStructPMatrixRefCount(pmatrix) --;
        if (hypre_SStructPMatrixRefCount(pmatrix) == 0)
        {
            stencils  = hypre_SStructPMatrixStencils(pmatrix);
            nvars     = hypre_SStructPMatrixNVars(pmatrix);
            smaps     = hypre_SStructPMatrixSMaps(pmatrix);
            sstencils = hypre_SStructPMatrixSStencils(pmatrix);
            smatrices = hypre_SStructPMatrixSMatrices(pmatrix);
            symmetric = hypre_SStructPMatrixSymmetric(pmatrix);
            for (vi = 0; vi < nvars; vi++)
            {
                HYPRE_SStructStencilDestroy(stencils[vi]);
                hypre_TFree(smaps[vi]);
                for (vj = 0; vj < nvars; vj++)
                {
                    hypre_StructStencilDestroy(sstencils[vi][vj]);
                    hypre_StructMatrixDestroy(smatrices[vi][vj]);
                }
                hypre_TFree(sstencils[vi]);
                hypre_TFree(smatrices[vi]);
                hypre_TFree(symmetric[vi]);
            }
            hypre_TFree(stencils);
            hypre_TFree(smaps);
            hypre_TFree(sstencils);
            hypre_TFree(smatrices);
            hypre_TFree(symmetric);
            hypre_TFree(hypre_SStructPMatrixSEntries(pmatrix));
            hypre_TFree(pmatrix);
        }
    }

    return hypre_error_flag;
}
Exemple #7
0
/*--------------------------------------------------------------------------
 * 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;
}
Exemple #8
0
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;
}
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;
}
Exemple #10
0
HYPRE_Int
hypre_AMR_CFCoarsen( hypre_SStructMatrix  *   A,
                     hypre_SStructMatrix  *   fac_A,
                     hypre_Index              refine_factors,
                     HYPRE_Int                level ) 

{
   MPI_Comm                comm       = hypre_SStructMatrixComm(A);
   hypre_SStructGraph     *graph      = hypre_SStructMatrixGraph(A);
   HYPRE_Int               graph_type = hypre_SStructGraphObjectType(graph);
   hypre_SStructGrid      *grid       = hypre_SStructGraphGrid(graph);
   HYPRE_Int               nUventries = hypre_SStructGraphNUVEntries(graph);
   HYPRE_IJMatrix          ij_A       = hypre_SStructMatrixIJMatrix(A);
   HYPRE_Int               matrix_type= hypre_SStructMatrixObjectType(A);
   HYPRE_Int               ndim       = hypre_SStructMatrixNDim(A);

   hypre_SStructPMatrix   *A_pmatrix;
   hypre_StructMatrix     *smatrix_var;
   hypre_StructStencil    *stencils;
   HYPRE_Int               stencil_size;
   hypre_Index             stencil_shape_i;
   hypre_Index             loop_size;
   hypre_Box               refined_box;
   double                **a_ptrs;
   hypre_Box              *A_dbox;

   HYPRE_Int               part_crse= level-1;
   HYPRE_Int               part_fine= level;
 
   hypre_BoxManager       *fboxman;
   hypre_BoxManEntry     **boxman_entries, *boxman_entry;
   HYPRE_Int               nboxman_entries;
   hypre_Box               boxman_entry_box;

   hypre_BoxArrayArray  ***fgrid_cinterface_extents;

   hypre_StructGrid       *cgrid;
   hypre_BoxArray         *cgrid_boxes;
   hypre_Box              *cgrid_box;
   hypre_Index             node_extents;
   hypre_Index             stridec, stridef;

   hypre_BoxArrayArray    *cinterface_arrays;
   hypre_BoxArray         *cinterface_array;
   hypre_Box              *fgrid_cinterface;

   HYPRE_Int               centre;

   HYPRE_Int               ci, fi, boxi;
   HYPRE_Int               max_stencil_size= 27;
   HYPRE_Int               false= 0;
   HYPRE_Int               true = 1;
   HYPRE_Int               found;
   HYPRE_Int              *stencil_ranks, *rank_stencils;
   HYPRE_Int               rank, startrank;
   double                 *vals;

   HYPRE_Int               i, j, iA;
   HYPRE_Int               nvars, var1; 

   hypre_Index             lindex, zero_index;
   hypre_Index             index1, index2;
   hypre_Index             index_temp;

   hypre_SStructUVEntry   *Uventry;
   HYPRE_Int               nUentries, cnt1;
   HYPRE_Int               box_array_size;

   HYPRE_Int              *ncols, *rows, *cols;
   
   HYPRE_Int              *temp1, *temp2;

   HYPRE_Int               myid;

   hypre_MPI_Comm_rank(comm, &myid);
   hypre_SetIndex(zero_index, 0, 0, 0);
   
   /*--------------------------------------------------------------------------
    *  Task: Coarsen the CF interface connections of A into fac_A so that 
    *  fac_A will have the stencil coefficients extending into a coarsened
    *  fbox. The centre coefficient is constructed to preserve the row sum.
    *--------------------------------------------------------------------------*/

   if (graph_type == HYPRE_SSTRUCT)
   {
      startrank   = hypre_SStructGridGhstartRank(grid);
   }
   if (graph_type == HYPRE_PARCSR)
   {
      startrank   = hypre_SStructGridStartRank(grid);
   }

   /*--------------------------------------------------------------------------
    * Fine grid strides by the refinement factors.
    *--------------------------------------------------------------------------*/
   hypre_SetIndex(stridec, 1, 1, 1);
   for (i= 0; i< ndim; i++)
   {
      stridef[i]= refine_factors[i];
   }
   for (i= ndim; i< 3; i++)
   {
      stridef[i]= 1;
   }

   /*--------------------------------------------------------------------------
    *  Determine the c/f interface index boxes: fgrid_cinterface_extents.
    *  These are between fpart= level and cpart= (level-1). The 
    *  fgrid_cinterface_extents are indexed by cboxes, but fboxes that
    *  abutt a given cbox must be considered. Moreover, for each fbox,
    *  we can have a c/f interface from a number of different stencil
    *  directions- i.e., we have a boxarrayarray for each cbox, each
    *  fbox leading to a boxarray.
    *
    *  Algo.: For each cbox:
    *    1) refine & stretch by a unit in each dimension.
    *    2) boxman_intersect with the fgrid boxman to get all fboxes contained
    *       or abutting this cbox.
    *    3) get the fgrid_cinterface_extents for each of these fboxes.
    *
    *  fgrid_cinterface_extents[var1][ci]
    *--------------------------------------------------------------------------*/
   A_pmatrix=  hypre_SStructMatrixPMatrix(fac_A, part_crse);
   nvars    =  hypre_SStructPMatrixNVars(A_pmatrix);

   fgrid_cinterface_extents= hypre_TAlloc(hypre_BoxArrayArray **, nvars);
   for (var1= 0; var1< nvars; var1++)
   {
      fboxman= hypre_SStructGridBoxManager(grid, part_fine, var1);
      stencils= hypre_SStructPMatrixSStencil(A_pmatrix, var1, var1);

      cgrid= hypre_SStructPGridSGrid(hypre_SStructPMatrixPGrid(A_pmatrix), var1);
      cgrid_boxes= hypre_StructGridBoxes(cgrid); 
      fgrid_cinterface_extents[var1]= hypre_TAlloc(hypre_BoxArrayArray *, 
                                                   hypre_BoxArraySize(cgrid_boxes));

      hypre_ForBoxI(ci, cgrid_boxes)
      {
         cgrid_box= hypre_BoxArrayBox(cgrid_boxes, ci);

         hypre_StructMapCoarseToFine(hypre_BoxIMin(cgrid_box), zero_index,
                                     refine_factors, hypre_BoxIMin(&refined_box));
         hypre_SetIndex(index1, refine_factors[0]-1, refine_factors[1]-1,
                        refine_factors[2]-1);
         hypre_StructMapCoarseToFine(hypre_BoxIMax(cgrid_box), index1,
                                     refine_factors, hypre_BoxIMax(&refined_box));

         /*------------------------------------------------------------------------
          * Stretch the refined_box so that a BoxManIntersect will get abutting
          * fboxes.
          *------------------------------------------------------------------------*/
         for (i= 0; i< ndim; i++)
         {
            hypre_BoxIMin(&refined_box)[i]-= 1;
            hypre_BoxIMax(&refined_box)[i]+= 1;
         }

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

         fgrid_cinterface_extents[var1][ci]= hypre_BoxArrayArrayCreate(nboxman_entries);

         /*------------------------------------------------------------------------
          * Get the  fgrid_cinterface_extents using var1-var1 stencil (only like-
          * variables couple).
          *------------------------------------------------------------------------*/
         if (stencils != NULL)
         {
            for (i= 0; i< nboxman_entries; i++)
            {
               hypre_BoxManEntryGetExtents(boxman_entries[i],
                                           hypre_BoxIMin(&boxman_entry_box),
                                           hypre_BoxIMax(&boxman_entry_box));
               hypre_CFInterfaceExtents2(&boxman_entry_box, cgrid_box, stencils, refine_factors,
                                         hypre_BoxArrayArrayBoxArray(fgrid_cinterface_extents[var1][ci], i) );
            }
         }
         hypre_TFree(boxman_entries);

      }  /* hypre_ForBoxI(ci, cgrid_boxes) */
   }     /* for (var1= 0; var1< nvars; var1++) */
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;
}
Exemple #12
0
int
hypre_SStructPMatrixCreate( MPI_Comm               comm,
                            hypre_SStructPGrid    *pgrid,
                            hypre_SStructStencil **stencils,
                            hypre_SStructPMatrix **pmatrix_ptr )
{
    hypre_SStructPMatrix  *pmatrix;
    int                    nvars;
    int                  **smaps;
    hypre_StructStencil ***sstencils;
    hypre_StructMatrix  ***smatrices;
    int                  **symmetric;

    hypre_StructStencil   *sstencil;
    int                   *vars;
    hypre_Index           *sstencil_shape;
    int                    sstencil_size;
    int                    new_dim;
    int                   *new_sizes;
    hypre_Index          **new_shapes;
    int                    size;
    hypre_StructGrid      *sgrid;

    int                    vi, vj;
    int                    i, j, k;

    pmatrix = hypre_TAlloc(hypre_SStructPMatrix, 1);

    hypre_SStructPMatrixComm(pmatrix)     = comm;
    hypre_SStructPMatrixPGrid(pmatrix)    = pgrid;
    hypre_SStructPMatrixStencils(pmatrix) = stencils;
    nvars = hypre_SStructPGridNVars(pgrid);
    hypre_SStructPMatrixNVars(pmatrix) = nvars;

    /* create sstencils */
    smaps     = hypre_TAlloc(int *, nvars);
    sstencils = hypre_TAlloc(hypre_StructStencil **, nvars);
    new_sizes  = hypre_TAlloc(int, nvars);
    new_shapes = hypre_TAlloc(hypre_Index *, nvars);
    size = 0;
    for (vi = 0; vi < nvars; vi++)
    {
        sstencils[vi] = hypre_TAlloc(hypre_StructStencil *, nvars);
        for (vj = 0; vj < nvars; vj++)
        {
            sstencils[vi][vj] = NULL;
            new_sizes[vj] = 0;
        }

        sstencil       = hypre_SStructStencilSStencil(stencils[vi]);
        vars           = hypre_SStructStencilVars(stencils[vi]);
        sstencil_shape = hypre_StructStencilShape(sstencil);
        sstencil_size  = hypre_StructStencilSize(sstencil);

        smaps[vi] = hypre_TAlloc(int, sstencil_size);
        for (i = 0; i < sstencil_size; i++)
        {
            j = vars[i];
            new_sizes[j]++;
        }
        for (vj = 0; vj < nvars; vj++)
        {
            if (new_sizes[vj])
            {
                new_shapes[vj] = hypre_TAlloc(hypre_Index, new_sizes[vj]);
                new_sizes[vj] = 0;
            }
        }
        for (i = 0; i < sstencil_size; i++)
        {
            j = vars[i];
            k = new_sizes[j];
            hypre_CopyIndex(sstencil_shape[i], new_shapes[j][k]);
            smaps[vi][i] = k;
            new_sizes[j]++;
        }
        new_dim = hypre_StructStencilDim(sstencil);
        for (vj = 0; vj < nvars; vj++)
        {
            if (new_sizes[vj])
            {
                sstencils[vi][vj] = hypre_StructStencilCreate(new_dim,
                                    new_sizes[vj],
                                    new_shapes[vj]);
            }
            size = hypre_max(size, new_sizes[vj]);
        }
    }
    hypre_SStructPMatrixSMaps(pmatrix)     = smaps;
    hypre_SStructPMatrixSStencils(pmatrix) = sstencils;
    hypre_TFree(new_sizes);
    hypre_TFree(new_shapes);

    /* create smatrices */
    smatrices = hypre_TAlloc(hypre_StructMatrix **, nvars);
    for (vi = 0; vi < nvars; vi++)
    {
        smatrices[vi] = hypre_TAlloc(hypre_StructMatrix *, nvars);
        for (vj = 0; vj < nvars; vj++)
        {
            smatrices[vi][vj] = NULL;
            if (sstencils[vi][vj] != NULL)
            {
                sgrid = hypre_SStructPGridSGrid(pgrid, vi);
                smatrices[vi][vj] =
                    hypre_StructMatrixCreate(comm, sgrid, sstencils[vi][vj]);
            }
        }
    }
    hypre_SStructPMatrixSMatrices(pmatrix) = smatrices;

    /* create symmetric */
    symmetric = hypre_TAlloc(int *, nvars);
    for (vi = 0; vi < nvars; vi++)
    {
        symmetric[vi] = hypre_TAlloc(int, nvars);
        for (vj = 0; vj < nvars; vj++)
        {
            symmetric[vi][vj] = 0;
        }
    }
    hypre_SStructPMatrixSymmetric(pmatrix) = symmetric;

    hypre_SStructPMatrixSEntriesSize(pmatrix) = size;
    hypre_SStructPMatrixSEntries(pmatrix) = hypre_TAlloc(int, size);

    hypre_SStructPMatrixRefCount(pmatrix)   = 1;

    *pmatrix_ptr = pmatrix;

    return hypre_error_flag;
}
/*--------------------------------------------------------------------------
 * 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 */
Exemple #14
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;
}