예제 #1
0
int 
HYPRE_StructMatrixSetBoxValues( HYPRE_StructMatrix  matrix,
                                int                *ilower,
                                int                *iupper,
                                int                 num_stencil_indices,
                                int                *stencil_indices,
                                double             *values )
{
   hypre_Index         new_ilower;
   hypre_Index         new_iupper;
   hypre_Box          *new_value_box;
                    
   int                 d;
   int                 ierr = 0;

   hypre_ClearIndex(new_ilower);
   hypre_ClearIndex(new_iupper);
   for (d = 0; d < hypre_StructGridDim(hypre_StructMatrixGrid(matrix)); d++)
   {
      hypre_IndexD(new_ilower, d) = ilower[d];
      hypre_IndexD(new_iupper, d) = iupper[d];
   }
   new_value_box = hypre_BoxCreate();
   hypre_BoxSetExtents(new_value_box, new_ilower, new_iupper);

   ierr = hypre_StructMatrixSetBoxValues(matrix, new_value_box,
                                         num_stencil_indices, stencil_indices,
                                         values, 0);

   hypre_BoxDestroy(new_value_box);

   return (ierr);
}
int 
HYPRE_StructVectorSetBoxValues( HYPRE_StructVector  vector,
                                int                *ilower,
                                int                *iupper,
                                double             *values )
{
   hypre_Index   new_ilower;
   hypre_Index   new_iupper;
   hypre_Box    *new_value_box;
                 
   int           d;
   int           ierr = 0;

   hypre_ClearIndex(new_ilower);
   hypre_ClearIndex(new_iupper);
   for (d = 0; d < hypre_StructGridDim(hypre_StructVectorGrid(vector)); d++)
   {
      hypre_IndexD(new_ilower, d) = ilower[d];
      hypre_IndexD(new_iupper, d) = iupper[d];
   }
   new_value_box = hypre_BoxCreate();
   hypre_BoxSetExtents(new_value_box, new_ilower, new_iupper);

   ierr = hypre_StructVectorSetBoxValues(vector, new_value_box, values, 0 );

   hypre_BoxDestroy(new_value_box);

   return ierr;
}
int
hypre_SMGRelaxSetBase( void        *relax_vdata,
                       hypre_Index  base_index,
                       hypre_Index  base_stride )
{
   hypre_SMGRelaxData *relax_data = relax_vdata;
   int                 d;
   int                 ierr = 0;
 
   for (d = 0; d < 3; d++)
   {
      hypre_IndexD((relax_data -> base_index),  d) =
         hypre_IndexD(base_index,  d);
      hypre_IndexD((relax_data -> base_stride), d) =
         hypre_IndexD(base_stride, d);
   }
 
   if ((relax_data -> base_box_array) != NULL)
   {
      hypre_BoxArrayDestroy((relax_data -> base_box_array));
      (relax_data -> base_box_array) = NULL;
   }

   (relax_data -> setup_temp_vec) = 1;
   (relax_data -> setup_a_rem)    = 1;
   (relax_data -> setup_a_sol)    = 1;

   return ierr;
}
예제 #4
0
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;
}
int
hypre_SMGRelaxSetNewMatrixStencil( void                *relax_vdata,
                                   hypre_StructStencil *diff_stencil )
{
   hypre_SMGRelaxData *relax_data = relax_vdata;

   hypre_Index        *stencil_shape = hypre_StructStencilShape(diff_stencil);
   int                 stencil_size  = hypre_StructStencilSize(diff_stencil); 
   int                 stencil_dim   = hypre_StructStencilDim(diff_stencil);
                         
   int                 i;
                     
   int                 ierr = 0;

   for (i = 0; i < stencil_size; i++)
   {
      if (hypre_IndexD(stencil_shape[i], (stencil_dim - 1)) != 0)
      {
         (relax_data -> setup_a_rem) = 1;
      }
      else
      {
         (relax_data -> setup_a_sol) = 1;
      }
   }

   return ierr;
}
예제 #6
0
파일: grow.c 프로젝트: 8l/insieme
hypre_BoxArray *
hypre_GrowBoxByStencil( hypre_Box           *box,
                        hypre_StructStencil *stencil,
                        int                  transpose )
{
   hypre_BoxArray   *grow_box_array;
                  
   hypre_BoxArray   *shift_box_array;
   hypre_Box        *shift_box;

   hypre_Index      *stencil_shape;

   int               s, d;

   stencil_shape = hypre_StructStencilShape(stencil);

   shift_box_array = hypre_BoxArrayCreate(hypre_StructStencilSize(stencil));
   shift_box = hypre_BoxCreate();
   for (s = 0; s < hypre_StructStencilSize(stencil); s++)
   {
      if (transpose)
         for (d = 0; d < 3; d++)
         {
            hypre_BoxIMinD(shift_box, d) =
               hypre_BoxIMinD(box, d) - hypre_IndexD(stencil_shape[s], d);
            hypre_BoxIMaxD(shift_box, d) =
               hypre_BoxIMaxD(box, d) - hypre_IndexD(stencil_shape[s], d);
         }
      else
         for (d = 0; d < 3; d++)
         {
            hypre_BoxIMinD(shift_box, d) =
               hypre_BoxIMinD(box, d) + hypre_IndexD(stencil_shape[s], d);
            hypre_BoxIMaxD(shift_box, d) =
               hypre_BoxIMaxD(box, d) + hypre_IndexD(stencil_shape[s], d);
         }

      hypre_CopyBox(shift_box, hypre_BoxArrayBox(shift_box_array, s));
   }
   hypre_BoxDestroy(shift_box);

   hypre_UnionBoxes(shift_box_array);
   grow_box_array = shift_box_array;

   return grow_box_array;
}
예제 #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
파일: smg.c 프로젝트: 5432935/crossbridge
int
hypre_SMGSetBase( void        *smg_vdata,
                  hypre_Index  base_index,
                  hypre_Index  base_stride )
{
   hypre_SMGData *smg_data = smg_vdata;
   int            d;
   int            ierr = 0;
 
   for (d = 0; d < 3; d++)
   {
      hypre_IndexD((smg_data -> base_index),  d) =
         hypre_IndexD(base_index,  d);
      hypre_IndexD((smg_data -> base_stride), d) =
         hypre_IndexD(base_stride, d);
   }
 
   return ierr;
}
예제 #9
0
HYPRE_Int
HYPRE_StructGridSetExtents( HYPRE_StructGrid  grid,
                            HYPRE_Int        *ilower,
                            HYPRE_Int        *iupper )
{
   hypre_Index  new_ilower;
   hypre_Index  new_iupper;

   HYPRE_Int    d;

   hypre_SetIndex(new_ilower, 0);
   hypre_SetIndex(new_iupper, 0);
   for (d = 0; d < hypre_StructGridNDim((hypre_StructGrid *) grid); d++)
   {
      hypre_IndexD(new_ilower, d) = ilower[d];
      hypre_IndexD(new_iupper, d) = iupper[d];
   }

   return ( hypre_StructGridSetExtents(grid, new_ilower, new_iupper) );
}
예제 #10
0
int
hypre_ProjectBox( hypre_Box    *box,
                  hypre_Index   index,
                  hypre_Index   stride )
{
   int  i, s, d, hl, hu, kl, ku;
   int  ierr = 0;

   /*------------------------------------------------------
    * project in all 3 dimensions
    *------------------------------------------------------*/

   for (d = 0; d < 3; d++)
   {

      i = hypre_IndexD(index, d);
      s = hypre_IndexD(stride, d);

      hl = hypre_BoxIMinD(box, d) - i;
      hu = hypre_BoxIMaxD(box, d) - i;

      if ( hl <= 0 )
         kl = (int) (hl / s);
      else
         kl = (int) ((hl + (s-1)) / s);

      if ( hu >= 0 )
         ku = (int) (hu / s);
      else
         ku = (int) ((hu - (s-1)) / s);

      hypre_BoxIMinD(box, d) = i + kl * s;
      hypre_BoxIMaxD(box, d) = i + ku * s;

   }

   return ierr;
}
예제 #11
0
HYPRE_Int
HYPRE_StructGridSetPeriodic( HYPRE_StructGrid  grid,
                             HYPRE_Int        *periodic )
{
   hypre_Index  new_periodic;

   HYPRE_Int    d;

   hypre_SetIndex(new_periodic, 0);
   for (d = 0; d < hypre_StructGridNDim(grid); d++)
   {
      hypre_IndexD(new_periodic, d) = periodic[d];
   }

   return ( hypre_StructGridSetPeriodic(grid, new_periodic) );
}
예제 #12
0
int
HYPRE_StructGridSetPeriodic( HYPRE_StructGrid  grid,
                             int              *periodic )
{
   hypre_Index  new_periodic;

   int          d;

   hypre_ClearIndex(new_periodic);
   for (d = 0; d < hypre_StructGridDim(grid); d++)
   {
      hypre_IndexD(new_periodic, d) = periodic[d];
   }

   return ( hypre_StructGridSetPeriodic(grid, new_periodic) );
}
예제 #13
0
HYPRE_Int 
HYPRE_StructVectorSetValues( HYPRE_StructVector  vector,
                             HYPRE_Int          *grid_index,
                             double              values )
{
   hypre_Index  new_grid_index;
                
   HYPRE_Int    d;

   hypre_ClearIndex(new_grid_index);
   for (d = 0; d < hypre_StructGridDim(hypre_StructVectorGrid(vector)); d++)
   {
      hypre_IndexD(new_grid_index, d) = grid_index[d];
   }

   hypre_StructVectorSetValues(vector, new_grid_index, &values, 0, -1, 0);

   return hypre_error_flag;
}
예제 #14
0
int
HYPRE_StructStencilSetElement( HYPRE_StructStencil  stencil,
                               int                  element_index,
                               int                 *offset )
{
   int           ierr = 0;
                
   hypre_Index  *shape;
   int           d;
 
   shape = hypre_StructStencilShape(stencil);
   hypre_ClearIndex(shape[element_index]);
   for (d = 0; d < hypre_StructStencilDim(stencil); d++)
   {
      hypre_IndexD(shape[element_index], d) = offset[d];
   }

   return ierr;
}
int 
HYPRE_StructVectorSetValues( HYPRE_StructVector  vector,
                             int                *grid_index,
                             double              values )
{
   hypre_Index  new_grid_index;
                
   int          d;
   int          ierr = 0;

   hypre_ClearIndex(new_grid_index);
   for (d = 0; d < hypre_StructGridDim(hypre_StructVectorGrid(vector)); d++)
   {
      hypre_IndexD(new_grid_index, d) = grid_index[d];
   }

   ierr = hypre_StructVectorSetValues(vector, new_grid_index, values, 0);

   return ierr;
}
예제 #16
0
int 
HYPRE_StructMatrixSetValues( HYPRE_StructMatrix  matrix,
                             int                *grid_index,
                             int                 num_stencil_indices,
                             int                *stencil_indices,
                             double             *values )
{
   hypre_Index  new_grid_index;
                
   int          d;
   int          ierr = 0;

   hypre_ClearIndex(new_grid_index);
   for (d = 0; d < hypre_StructGridDim(hypre_StructMatrixGrid(matrix)); d++)
   {
      hypre_IndexD(new_grid_index, d) = grid_index[d];
   }

   ierr = hypre_StructMatrixSetValues(matrix, new_grid_index,
                                      num_stencil_indices, stencil_indices,
                                      values, 0);

   return (ierr);
}
예제 #17
0
HYPRE_Int
hypre_StructStencilSymmetrize( hypre_StructStencil  *stencil,
                               hypre_StructStencil **symm_stencil_ptr,
                               HYPRE_Int           **symm_elements_ptr )
{
   hypre_Index          *stencil_shape = hypre_StructStencilShape(stencil);
   HYPRE_Int             stencil_size  = hypre_StructStencilSize(stencil); 

   hypre_StructStencil  *symm_stencil;
   hypre_Index          *symm_stencil_shape;
   HYPRE_Int             symm_stencil_size;
   HYPRE_Int            *symm_elements;

   HYPRE_Int             no_symmetric_stencil_element;
   HYPRE_Int             i, j, d;
                       
   /*------------------------------------------------------
    * Copy stencil elements into `symm_stencil_shape'
    *------------------------------------------------------*/

   symm_stencil_shape = hypre_CTAlloc(hypre_Index, 2*stencil_size);
   for (i = 0; i < stencil_size; i++)
   {
      hypre_CopyIndex(stencil_shape[i], symm_stencil_shape[i]);
   }

   /*------------------------------------------------------
    * Create symmetric stencil elements and `symm_elements'
    *------------------------------------------------------*/

   symm_elements = hypre_CTAlloc(HYPRE_Int, 2*stencil_size);
   for (i = 0; i < 2*stencil_size; i++)
      symm_elements[i] = -1;

   symm_stencil_size = stencil_size;
   for (i = 0; i < stencil_size; i++)
   {
      if (symm_elements[i] < 0)
      {
         /* note: start at i to handle "center" element correctly */
         no_symmetric_stencil_element = 1;
         for (j = i; j < stencil_size; j++)
         {
            if ( (hypre_IndexX(symm_stencil_shape[j]) ==
                  -hypre_IndexX(symm_stencil_shape[i])  ) &&
                 (hypre_IndexY(symm_stencil_shape[j]) ==
                  -hypre_IndexY(symm_stencil_shape[i])  ) &&
                 (hypre_IndexZ(symm_stencil_shape[j]) ==
                  -hypre_IndexZ(symm_stencil_shape[i])  )   )
            {
               /* only "off-center" elements have symmetric entries */
               if (i != j)
                  symm_elements[j] = i;
               no_symmetric_stencil_element = 0;
            }
         }

         if (no_symmetric_stencil_element)
         {
            /* add symmetric stencil element to `symm_stencil' */
            for (d = 0; d < 3; d++)
            {
               hypre_IndexD(symm_stencil_shape[symm_stencil_size], d) =
                  -hypre_IndexD(symm_stencil_shape[i], d);
            }
               
            symm_elements[symm_stencil_size] = i;
            symm_stencil_size++;
         }
      }
   }

   symm_stencil = hypre_StructStencilCreate(hypre_StructStencilDim(stencil),
                                            symm_stencil_size,
                                            symm_stencil_shape);

   *symm_stencil_ptr  = symm_stencil;
   *symm_elements_ptr = symm_elements;

   return hypre_error_flag;
}
예제 #18
0
파일: sstruct_matrix.c 프로젝트: 8l/insieme
int
hypre_SStructUMatrixSetValues( hypre_SStructMatrix *matrix,
                               int                  part,
                               hypre_Index          index,
                               int                  var,
                               int                  nentries,
                               int                 *entries,
                               double              *values,
                               int                  add_to )
{
    HYPRE_IJMatrix        ijmatrix = hypre_SStructMatrixIJMatrix(matrix);
    hypre_SStructGraph   *graph   = hypre_SStructMatrixGraph(matrix);
    hypre_SStructGrid    *grid    = hypre_SStructGraphGrid(graph);
    hypre_SStructStencil *stencil = hypre_SStructGraphStencil(graph, part, var);
    int                  *vars    = hypre_SStructStencilVars(stencil);
    hypre_Index          *shape   = hypre_SStructStencilShape(stencil);
    int                   size    = hypre_SStructStencilSize(stencil);
    hypre_IndexRef        offset;
    hypre_Index           to_index;
    hypre_SStructUVEntry *Uventry;
    hypre_BoxMapEntry    *map_entry;
    hypre_SStructMapInfo *entry_info;
    HYPRE_BigInt          row_coord;
    HYPRE_BigInt         *col_coords;
    int                   ncoeffs;
    double               *coeffs;
    int                   i, entry;
    int                   proc, myproc;
    /* GEC1002 the matrix type */
    int                   matrix_type = hypre_SStructMatrixObjectType(matrix);

    hypre_SStructGridFindMapEntry(grid, part, index, var, &map_entry);
    if (map_entry == NULL)
    {
        hypre_error_in_arg(1);
        hypre_error_in_arg(2);
        hypre_error_in_arg(3);
        /* RDF: This printing shouldn't be on by default */
        printf("Warning: Attempt to set coeffs for point not in grid\n");
        printf("hypre_SStructUMatrixSetValues call aborted for grid point\n");
        printf("    part=%d, var=%d, index=(%d, %d, %d)\n", part, var,
               hypre_IndexD(index,0),
               hypre_IndexD(index,1),
               hypre_IndexD(index,2) );
        return hypre_error_flag;
    }
    else
    {
        hypre_BoxMapEntryGetInfo(map_entry, (void **) &entry_info);
    }

    /* Only Set values if I am the owner process; off-process AddTo and Get
     * values are done by IJ */
    if (!add_to)
    {
        hypre_SStructMapEntryGetProcess(map_entry, &proc);
        MPI_Comm_rank(hypre_SStructGridComm(grid), &myproc);
        if (proc != myproc)
        {
            return hypre_error_flag;
        }
    }

    /* GEC1002 get the rank using the function with the type=matrixtype*/
    hypre_SStructMapEntryGetGlobalRank(map_entry, index, &row_coord, matrix_type);


    col_coords = hypre_SStructMatrixTmpColCoords(matrix);
    coeffs     = hypre_SStructMatrixTmpCoeffs(matrix);
    ncoeffs = 0;
    for (i = 0; i < nentries; i++)
    {
        entry = entries[i];

        if (entry < size)
        {
            /* stencil entries */
            offset = shape[entry];
            hypre_IndexX(to_index) = hypre_IndexX(index) + hypre_IndexX(offset);
            hypre_IndexY(to_index) = hypre_IndexY(index) + hypre_IndexY(offset);
            hypre_IndexZ(to_index) = hypre_IndexZ(index) + hypre_IndexZ(offset);

            hypre_SStructGridFindMapEntry(grid, part, to_index, vars[entry],
                                          &map_entry);

            if (map_entry != NULL)
            {


                hypre_SStructMapEntryGetGlobalRank(map_entry, to_index,
                                                   &col_coords[ncoeffs],matrix_type);


                coeffs[ncoeffs] = values[i];
                ncoeffs++;
            }
        }
        else
        {
            /* non-stencil entries */
            entry -= size;
            hypre_SStructGraphFindUVEntry(graph, part, index, var, &Uventry);

            col_coords[ncoeffs] = hypre_SStructUVEntryRank(Uventry, entry);
            coeffs[ncoeffs] = values[i];
            ncoeffs++;
        }
    }

    if (add_to > 0)
    {
        HYPRE_IJMatrixAddToValues(ijmatrix, 1, &ncoeffs, &row_coord,
                                  (const HYPRE_BigInt *) col_coords,
                                  (const double *) coeffs);
    }
    else if (add_to > -1)
    {
        HYPRE_IJMatrixSetValues(ijmatrix, 1, &ncoeffs, &row_coord,
                                (const HYPRE_BigInt *) col_coords,
                                (const double *) coeffs);
    }
    else
    {
        HYPRE_IJMatrixGetValues(ijmatrix, 1, &ncoeffs, &row_coord,
                                col_coords, values);
    }

    return hypre_error_flag;
}
int
hypre_SMGRelaxSetupARem( void               *relax_vdata,
                         hypre_StructMatrix *A,
                         hypre_StructVector *b,
                         hypre_StructVector *x           )
{
   hypre_SMGRelaxData   *relax_data = relax_vdata;

   int                   num_spaces    = (relax_data -> num_spaces);
   int                  *space_indices = (relax_data -> space_indices);
   int                  *space_strides = (relax_data -> space_strides);
   hypre_StructVector   *temp_vec      = (relax_data -> temp_vec);

   hypre_StructStencil  *stencil       = hypre_StructMatrixStencil(A);     
   hypre_Index          *stencil_shape = hypre_StructStencilShape(stencil);
   int                   stencil_size  = hypre_StructStencilSize(stencil); 
   int                   stencil_dim   = hypre_StructStencilDim(stencil);
                       
   hypre_StructMatrix   *A_rem;
   void                **residual_data;

   hypre_Index           base_index;
   hypre_Index           base_stride;

   int                   num_stencil_indices;
   int                  *stencil_indices;
                       
   int                   i;

   int                   ierr = 0;

   /*----------------------------------------------------------
    * Free up old data before putting new data into structure
    *----------------------------------------------------------*/

   hypre_SMGRelaxDestroyARem(relax_vdata);

   /*----------------------------------------------------------
    * Set up data
    *----------------------------------------------------------*/

   hypre_CopyIndex((relax_data -> base_index),  base_index);
   hypre_CopyIndex((relax_data -> base_stride), base_stride);

   stencil_indices = hypre_TAlloc(int, stencil_size);
   num_stencil_indices = 0;
   for (i = 0; i < stencil_size; i++)
   {
      if (hypre_IndexD(stencil_shape[i], (stencil_dim - 1)) != 0)
      {
         stencil_indices[num_stencil_indices] = i;
         num_stencil_indices++;
      }
   }
   A_rem = hypre_StructMatrixCreateMask(A, num_stencil_indices, stencil_indices);
   hypre_TFree(stencil_indices);

   /* Set up residual_data */
   residual_data = hypre_TAlloc(void *, num_spaces);

   for (i = 0; i < num_spaces; i++)
   {
      hypre_IndexD(base_index,  (stencil_dim - 1)) = space_indices[i];
      hypre_IndexD(base_stride, (stencil_dim - 1)) = space_strides[i];

      residual_data[i] = hypre_SMGResidualCreate();
      hypre_SMGResidualSetBase(residual_data[i], base_index, base_stride);
      hypre_SMGResidualSetup(residual_data[i], A_rem, x, b, temp_vec);
   }

   (relax_data -> A_rem)         = A_rem;
   (relax_data -> residual_data) = residual_data;

   (relax_data -> setup_a_rem) = 0;

   return ierr;
}
예제 #20
0
/*--------------------------------------------------------------------------
 * hypre_Maxwell_Grad.c
 *   Forms a node-to-edge gradient operator. Looping over the
 *   edge grid so that each processor fills up only its own rows. Each 
 *   processor will have its processor interface nodal ranks.
 *   Loops over two types of boxes, interior of grid boxes and boundary
 *   of boxes. Algo:
 *       find all nodal and edge physical boundary points and set 
 *       the appropriate flag to be 0 at a boundary dof.
 *       set -1's in value array
 *       for each edge box, 
 *       for interior 
 *       {
 *          connect edge ijk (row) to nodes (col) connected to this edge
 *          and change -1 to 1 if needed;
 *       }
 *       for boundary layers
 *       {
 *          if edge not on the physical boundary connect only the nodes
 *          that are not on the physical boundary
 *       }
 *       set parcsr matrix with values;
 *
 * Note that the nodes that are on the processor interface can be 
 * on the physical boundary. But the off-proc edges connected to this
 * type of node will be a physical boundary edge.
 *
 *--------------------------------------------------------------------------*/
hypre_ParCSRMatrix *
hypre_Maxwell_Grad(hypre_SStructGrid    *grid)
{
   MPI_Comm               comm = (grid ->  comm);

   HYPRE_IJMatrix         T_grad;
   hypre_ParCSRMatrix    *parcsr_grad;
   HYPRE_Int              matrix_type= HYPRE_PARCSR;

   hypre_SStructGrid     *node_grid, *edge_grid;

   hypre_SStructPGrid    *pgrid;
   hypre_StructGrid      *var_grid;
   hypre_BoxArray        *boxes, *tmp_box_array1, *tmp_box_array2;
   hypre_BoxArray        *node_boxes, *edge_boxes, *cell_boxes;
   hypre_Box             *box, *cell_box;
   hypre_Box              layer, interior_box;
   hypre_Box             *box_piece;

   hypre_BoxManager      *boxman;
   hypre_BoxManEntry     *entry;

   HYPRE_Int             *inode, *jedge;
   HYPRE_Int              nrows, nnodes, *nflag, *eflag, *ncols;
   HYPRE_Real            *vals;

   hypre_Index            index;
   hypre_Index            loop_size, start, lindex;
   hypre_Index            shift, shift2;
   hypre_Index           *offsets, *varoffsets;

   HYPRE_Int              nparts= hypre_SStructGridNParts(grid);
   HYPRE_Int              ndim  = hypre_SStructGridNDim(grid);

   HYPRE_SStructVariable  vartype_node, *vartype_edges;
   HYPRE_SStructVariable *vartypes;

   HYPRE_Int              nvars, part;

   HYPRE_Int              i, j, k, m, n, d;
   HYPRE_Int             *direction, ndirection;

   HYPRE_Int              ilower, iupper;
   HYPRE_Int              jlower, jupper;

   HYPRE_Int              start_rank1, start_rank2, rank;

   HYPRE_Int              myproc;
   HYPRE_Int              ierr=0;

   hypre_BoxInit(&layer, ndim);
   hypre_BoxInit(&interior_box, ndim);

   hypre_MPI_Comm_rank(comm, &myproc);

   hypre_ClearIndex(shift);
   for (i= 0; i< ndim; i++)
   {
      hypre_IndexD(shift, i)= -1;
   }

   /* To get the correct ranks, separate node & edge grids must be formed. 
      Note that the edge vars must be ordered the same way as is in grid.*/
   HYPRE_SStructGridCreate(comm, ndim, nparts, &node_grid);
   HYPRE_SStructGridCreate(comm, ndim, nparts, &edge_grid);

   vartype_node = HYPRE_SSTRUCT_VARIABLE_NODE;
   vartype_edges= hypre_TAlloc(HYPRE_SStructVariable, ndim);

   /* Assuming the same edge variable types on all parts */
   pgrid   = hypre_SStructGridPGrid(grid, 0);
   vartypes= hypre_SStructPGridVarTypes(pgrid);
   nvars   = hypre_SStructPGridNVars(pgrid);

   k= 0;
   for (i= 0; i< nvars; i++)
   {
      j= vartypes[i];
      switch(j)
      {
         case 2:
         {
            vartype_edges[k]= HYPRE_SSTRUCT_VARIABLE_XFACE;
            k++;
            break;
         }

         case 3:
         {
            vartype_edges[k]= HYPRE_SSTRUCT_VARIABLE_YFACE;
            k++;
            break;
         }

         case 5:
         {
            vartype_edges[k]= HYPRE_SSTRUCT_VARIABLE_XEDGE;
            k++;
            break;
         }

         case 6:
         {
            vartype_edges[k]= HYPRE_SSTRUCT_VARIABLE_YEDGE;
            k++;
            break;
         }

         case 7:
         {
            vartype_edges[k]= HYPRE_SSTRUCT_VARIABLE_ZEDGE;
            k++;
            break;
         }

      }  /* switch(j) */
   }     /* for (i= 0; i< nvars; i++) */

   for (part= 0; part< nparts; part++)
   {
      pgrid= hypre_SStructGridPGrid(grid, part);  
      var_grid= hypre_SStructPGridCellSGrid(pgrid) ;

      boxes= hypre_StructGridBoxes(var_grid);
      hypre_ForBoxI(j, boxes)
      {
         box= hypre_BoxArrayBox(boxes, j);
         HYPRE_SStructGridSetExtents(node_grid, part,
                                     hypre_BoxIMin(box), hypre_BoxIMax(box));
         HYPRE_SStructGridSetExtents(edge_grid, part,
                                     hypre_BoxIMin(box), hypre_BoxIMax(box));
      }
      HYPRE_SStructGridSetVariables(node_grid, part, 1, &vartype_node);
      HYPRE_SStructGridSetVariables(edge_grid, part, ndim, vartype_edges);
   }
예제 #21
0
파일: new_assemble.c 프로젝트: 8l/insieme
int hypre_StructGridAssembleWithAP( hypre_StructGrid *grid )
{
 


   int                  ierr = 0;
   int                  tmp_i;
   
   int                  size, global_num_boxes, num_local_boxes;
   int                  i, j, d, k, index;
   int                  num_procs, myid;
   int                  *sendbuf8, *recvbuf8, *sendbuf2, *recvbuf2;
   int                  min_box_size, max_box_size;
   int                  global_min_box_size, global_max_box_size;
   int                 *ids;
   int                  max_regions, max_refinements, ologp;
   double               gamma;
   hypre_Index          min_index, max_index;
   
  
   int                  prune;
       
   hypre_Box           *box;
   

   MPI_Comm             comm         = hypre_StructGridComm(grid);
   hypre_Box           *bounding_box = hypre_StructGridBoundingBox(grid);
   hypre_BoxArray      *local_boxes  = hypre_StructGridBoxes(grid);
   int                  dim          = hypre_StructGridDim(grid);
   hypre_BoxNeighbors  *neighbors    = hypre_StructGridNeighbors(grid);
   int                  max_distance = hypre_StructGridMaxDistance(grid);
   hypre_IndexRef       periodic     = hypre_StructGridPeriodic(grid);

   int                 *local_boxnums;

   double               dbl_global_size, tmp_dbl;
   
   hypre_BoxArray       *my_partition;
   int                  *part_ids, *part_boxnums;
     
   int                  *proc_array, proc_count, proc_alloc, count;
   int                  *tmp_proc_ids = NULL;
   
   int                  max_response_size;
   int                  *ap_proc_ids, *send_buf, *send_buf_starts;
   int                  *response_buf, *response_buf_starts;

   hypre_BoxArray      *neighbor_boxes, *n_boxes_copy;
   int                 *neighbor_proc_ids, *neighbor_boxnums;

   int                 *order_index, *delete_array;
   int                 tmp_id, start, first_local;
   
   int                 grow, grow_array[6];
   hypre_Box           *grow_box;
   
   
   int                  *numghost;
   int                   ghostsize;
   hypre_Box            *ghostbox;

   hypre_StructAssumedPart     *assumed_part;
   hypre_DataExchangeResponse  response_obj;
 
   int                  px = hypre_IndexX(periodic);
   int                  py = hypre_IndexY(periodic);
   int                  pz = hypre_IndexZ(periodic);

   int                  i_periodic = px ? 1 : 0;
   int                  j_periodic = py ? 1 : 0;
   int                  k_periodic = pz ? 1 : 0;

   int                  num_periods, multiple_ap, p;
   hypre_Box           *result_box, *period_box;
   hypre_Index         *pshifts;

   hypre_IndexRef       pshift;

#if NEIGH_PRINT
   double               start_time, end_time;
   
#endif



/*---------------------------------------------
  Step 1:  Initializations
  -----------------------------------------------*/

   prune = 1; /* default is to prune */ 
   
   num_local_boxes = hypre_BoxArraySize(local_boxes);
  
   num_periods = (1+2*i_periodic) * (1+2*j_periodic) * (1+2*k_periodic);


   MPI_Comm_size(comm, &num_procs);
   MPI_Comm_rank(comm, &myid);


 
/*---------------------------------------------
  Step 2:  Determine the global size, total number of boxes,
           and global bounding box.
           Also get the min and max box sizes
           since it is convenient to do so.
  -----------------------------------------------*/

   if (neighbors == NULL) 
   {
    
      /*these may not be needed - check later */
      ids =   hypre_TAlloc(int, num_local_boxes);
    
      /* for the vol and number of boxes */
      sendbuf2 = hypre_CTAlloc(int, 2);
      recvbuf2 = hypre_CTAlloc(int, 2);
      size = 0;
     
      bounding_box = hypre_BoxCreate();
      grow_box = hypre_BoxCreate();
      

      if (num_local_boxes) 
      {
         
         min_box_size = hypre_BoxVolume( hypre_BoxArrayBox(local_boxes, 0));
         max_box_size = hypre_BoxVolume( hypre_BoxArrayBox(local_boxes, 0));


         /* initialize min and max */
         for (d=0; d<3; d++)
         {
            hypre_IndexD(min_index, d) = pow(2,30); 
            hypre_IndexD(max_index, d) = -pow(2,30);
         }
         

         hypre_ForBoxI(i, local_boxes)
         {
            box = hypre_BoxArrayBox(local_boxes, i);
            /* get global size and number of boxes */ 
            tmp_i = hypre_BoxVolume(box);
            size += tmp_i;
            min_box_size = hypre_min(min_box_size, tmp_i);
            max_box_size = hypre_max(max_box_size, tmp_i);


            /* set id */  
            ids[i] = i;


            /* 1/3/05 we need this for the case of holes in the domain. (I had
               commented
               it out on 12/04 - as I thought this was not necessary. */
            
            
            /* zero volume boxes - still look at for getting the bounding box */
            if (hypre_BoxVolume(box) == 0) /* zero volume boxes - still count */
            {
               hypre_CopyBox(box, grow_box);
               for (d = 0; d < 3; d++)
               {
                  if(!hypre_BoxSizeD(box, d))
                  {
                     grow = (hypre_BoxIMinD(box, d) - hypre_BoxIMaxD(box, d) + 1)/2;
                     grow_array[2*d] = grow;
                     grow_array[2*d+1] = grow;
                  }
                  else
                  {
                     grow_array[2*d] = 0;
                     grow_array[2*d+1] = 0;
                  }
               }   
               /* expand the box */
               hypre_BoxExpand(grow_box, grow_array);
               box = grow_box; /*pointer copy*/
            }     
            /*now we have a vol > 0 box */
    
         
            for (d = 0; d < dim; d++) /* for each dimension */
            {
               hypre_IndexD(min_index, d) = hypre_min( hypre_IndexD(min_index, d), 
                                                       hypre_BoxIMinD(box, d));
               hypre_IndexD(max_index, d) = hypre_max( hypre_IndexD(max_index, d), 
                                                       hypre_BoxIMaxD(box, d));
            }
                        
         }/*end for each box loop */

         /* bounding box extents */ 
         hypre_BoxSetExtents(bounding_box, min_index, max_index);
   
      }
예제 #22
0
파일: struct_io.c 프로젝트: ducpdx/hypre
HYPRE_Int
hypre_PrintBoxArrayData( FILE            *file,
                         hypre_BoxArray  *box_array,
                         hypre_BoxArray  *data_space,
                         HYPRE_Int        num_values,
                         HYPRE_Int        dim,
                         HYPRE_Complex   *data       )
{
   hypre_Box       *box;
   hypre_Box       *data_box;
                   
   HYPRE_Int        data_box_volume;
   HYPRE_Int        datai;
                   
   hypre_Index      loop_size;
   hypre_IndexRef   start;
   hypre_Index      stride;
   hypre_Index      index;
                   
   HYPRE_Int        i, j, d;
   HYPRE_Complex    value;

   /*----------------------------------------
    * Print data
    *----------------------------------------*/

   hypre_SetIndex(stride, 1);

   hypre_ForBoxI(i, box_array)
   {
      box      = hypre_BoxArrayBox(box_array, i);
      data_box = hypre_BoxArrayBox(data_space, i);

      start = hypre_BoxIMin(box);
      data_box_volume = hypre_BoxVolume(data_box);

      hypre_BoxGetSize(box, loop_size);

      hypre_BoxLoop1Begin(dim, loop_size,
                          data_box, start, stride, datai);
      hypre_BoxLoop1For(datai)
      {
         /* Print lines of the form: "%d: (%d, %d, %d; %d) %.14e\n" */
         hypre_BoxLoopGetIndex(index);
         for (j = 0; j < num_values; j++)
         {
            hypre_fprintf(file, "%d: (%d",
                          i, hypre_IndexD(start, 0) + hypre_IndexD(index, 0));
            for (d = 1; d < dim; d++)
            {
               hypre_fprintf(file, ", %d",
                             hypre_IndexD(start, d) + hypre_IndexD(index, d));
            }
            value = data[datai + j*data_box_volume];
#ifdef HYPRE_COMPLEX
            hypre_fprintf(file, "; %d) %.14e , %.14e\n",
                          j, hypre_creal(value), hypre_cimag(value));
#else
            hypre_fprintf(file, "; %d) %.14e\n", j, value);
#endif
         }
      }
      hypre_BoxLoop1End(datai);

      data += num_values*data_box_volume;
   }
예제 #23
0
int
hypre_StructMatrixInitializeShell( hypre_StructMatrix *matrix )
{
    int    ierr = 0;

    hypre_StructGrid     *grid;

    hypre_StructStencil  *user_stencil;
    hypre_StructStencil  *stencil;
    hypre_Index          *stencil_shape;
    int                   stencil_size;
    int                   num_values;
    int                  *symm_elements;

    int                  *num_ghost;
    int                   extra_ghost[] = {0, 0, 0, 0, 0, 0};

    hypre_BoxArray       *data_space;
    hypre_BoxArray       *boxes;
    hypre_Box            *box;
    hypre_Box            *data_box;

    int                 **data_indices;
    int                   data_size;
    int                   data_box_volume;

    int                   i, j, d;

    grid = hypre_StructMatrixGrid(matrix);

    /*-----------------------------------------------------------------------
     * Set up stencil and num_values:
     *    The stencil is a "symmetrized" version of the user's stencil
     *    as computed by hypre_StructStencilSymmetrize.
     *
     *    The `symm_elements' array is used to determine what data is
     *    explicitely stored (symm_elements[i] < 0) and what data does is
     *    not explicitely stored (symm_elements[i] >= 0), but is instead
     *    stored as the transpose coefficient at a neighboring grid point.
     *-----------------------------------------------------------------------*/

    if (hypre_StructMatrixStencil(matrix) == NULL)
    {
        user_stencil = hypre_StructMatrixUserStencil(matrix);

        hypre_StructStencilSymmetrize(user_stencil, &stencil, &symm_elements);

        stencil_shape = hypre_StructStencilShape(stencil);
        stencil_size  = hypre_StructStencilSize(stencil);

        if (!hypre_StructMatrixSymmetric(matrix))
        {
            /* store all element data */
            for (i = 0; i < stencil_size; i++)
                symm_elements[i] = -1;
            num_values = stencil_size;
        }
        else
        {
            num_values = (stencil_size + 1) / 2;
        }

        hypre_StructMatrixStencil(matrix)   = stencil;
        hypre_StructMatrixSymmElements(matrix) = symm_elements;
        hypre_StructMatrixNumValues(matrix) = num_values;
    }

    /*-----------------------------------------------------------------------
     * Set ghost-layer size for symmetric storage
     *   - All stencil coeffs are to be available at each point in the
     *     grid, as well as in the user-specified ghost layer.
     *-----------------------------------------------------------------------*/

    num_ghost     = hypre_StructMatrixNumGhost(matrix);
    stencil       = hypre_StructMatrixStencil(matrix);
    stencil_shape = hypre_StructStencilShape(stencil);
    stencil_size  = hypre_StructStencilSize(stencil);
    symm_elements = hypre_StructMatrixSymmElements(matrix);

    for (i = 0; i < stencil_size; i++)
    {
        if (symm_elements[i] >= 0)
        {
            for (d = 0; d < 3; d++)
            {
                extra_ghost[2*d] =
                    hypre_max(extra_ghost[2*d], -hypre_IndexD(stencil_shape[i], d));
                extra_ghost[2*d + 1] =
                    hypre_max(extra_ghost[2*d + 1],  hypre_IndexD(stencil_shape[i], d));
            }
        }
    }

    for (d = 0; d < 3; d++)
    {
        num_ghost[2*d]     += extra_ghost[2*d];
        num_ghost[2*d + 1] += extra_ghost[2*d + 1];
    }

    /*-----------------------------------------------------------------------
     * Set up data_space
     *-----------------------------------------------------------------------*/

    if (hypre_StructMatrixDataSpace(matrix) == NULL)
    {
        boxes = hypre_StructGridBoxes(grid);
        data_space = hypre_BoxArrayCreate(hypre_BoxArraySize(boxes));

        hypre_ForBoxI(i, boxes)
        {
            box = hypre_BoxArrayBox(boxes, i);
            data_box = hypre_BoxArrayBox(data_space, i);

            hypre_CopyBox(box, data_box);
            for (d = 0; d < 3; d++)
            {
                hypre_BoxIMinD(data_box, d) -= num_ghost[2*d];
                hypre_BoxIMaxD(data_box, d) += num_ghost[2*d + 1];
            }
        }
예제 #24
0
HYPRE_Int
hypre_GeneralBoxBoundaryIntersect( hypre_Box *box,
                            hypre_StructGrid *grid,
                            hypre_Index stencil_element,
                            hypre_BoxArray *boundary )
{
   hypre_BoxManager   *boxman;
   hypre_BoxManEntry **entries;
   hypre_BoxArray     *int_boxes, *tmp_boxes;
   hypre_Box          *bbox, *ibox;
   HYPRE_Int           nentries, i, j;
   HYPRE_Int          *dd;
   HYPRE_Int           ndim;

   ndim = hypre_StructGridNDim(grid);
   dd = hypre_CTAlloc(HYPRE_Int, ndim);

   for (i=0; i < ndim; i++)
     dd[i] = hypre_IndexD(stencil_element, i);

   /* set bbox to the box surface of interest */
   hypre_BoxArraySetSize(boundary, 1);
   bbox = hypre_BoxArrayBox(boundary, 0);
   hypre_CopyBox(box, bbox);

   /* temporarily shift bbox in direction dir and intersect with the grid */
   for (i=0; i < ndim; i++)
   {
      hypre_BoxIMinD(bbox, i) += dd[i];
      hypre_BoxIMaxD(bbox, i) += dd[i];
   }

   boxman = hypre_StructGridBoxMan(grid);
   hypre_BoxManIntersect(boxman, hypre_BoxIMin(bbox), hypre_BoxIMax(bbox),
                         &entries, &nentries);
   for (i=0; i < ndim; i++)
   {
      hypre_BoxIMinD(bbox, i) -= dd[i];
      hypre_BoxIMaxD(bbox, i) -= dd[i];
   }

   /* shift intersected boxes in direction -dir and subtract from bbox */
   int_boxes  = hypre_BoxArrayCreate(nentries, ndim);
   tmp_boxes  = hypre_BoxArrayCreate(0, ndim);
   for (i = 0; i < nentries; i++)
   {
      ibox = hypre_BoxArrayBox(int_boxes, i);
      hypre_BoxManEntryGetExtents(
         entries[i], hypre_BoxIMin(ibox), hypre_BoxIMax(ibox));
      for (j=0; j < ndim; j++)
      {
         hypre_BoxIMinD(ibox, j) -= dd[j];
         hypre_BoxIMaxD(ibox, j) -= dd[j];
      }
   }
   hypre_SubtractBoxArrays(boundary, int_boxes, tmp_boxes);

   hypre_BoxArrayDestroy(int_boxes);
   hypre_BoxArrayDestroy(tmp_boxes);
   hypre_TFree(entries);
   hypre_TFree(dd);

   return hypre_error_flag;
}
예제 #25
0
int
hypre_CreateComputeInfo( hypre_StructGrid      *grid,
                         hypre_StructStencil   *stencil,
                         hypre_ComputeInfo    **compute_info_ptr )
{
   int                      ierr = 0;

   hypre_CommInfo          *comm_info;
   hypre_BoxArrayArray     *indt_boxes;
   hypre_BoxArrayArray     *dept_boxes;

   hypre_BoxArray          *boxes;

   hypre_BoxArray          *cbox_array;
   hypre_Box               *cbox;

   int                      i;

#ifdef HYPRE_OVERLAP_COMM_COMP
   hypre_Box               *rembox;
   hypre_Index             *stencil_shape;
   int                      border[3][2] = {{0, 0}, {0, 0}, {0, 0}};
   int                      cbox_array_size;
   int                      s, d;
#endif

   /*------------------------------------------------------
    * Extract needed grid info
    *------------------------------------------------------*/

   boxes = hypre_StructGridBoxes(grid);

   /*------------------------------------------------------
    * Get communication info
    *------------------------------------------------------*/

   hypre_CreateCommInfoFromStencil(grid, stencil, &comm_info);

#ifdef HYPRE_OVERLAP_COMM_COMP

   /*------------------------------------------------------
    * Compute border info
    *------------------------------------------------------*/

   stencil_shape = hypre_StructStencilShape(stencil);
   for (s = 0; s < hypre_StructStencilSize(stencil); s++)
   {
      for (d = 0; d < 3; d++)
      {
         i = hypre_IndexD(stencil_shape[s], d);
         if (i < 0)
         {
            border[d][0] = hypre_max(border[d][0], -i);
         }
         else if (i > 0)
         {
            border[d][1] = hypre_max(border[d][1], i);
         }
      }
   }

   /*------------------------------------------------------
    * Set up the dependent boxes
    *------------------------------------------------------*/

   dept_boxes = hypre_BoxArrayArrayCreate(hypre_BoxArraySize(boxes));

   rembox = hypre_BoxCreate();
   hypre_ForBoxI(i, boxes)
      {
         cbox_array = hypre_BoxArrayArrayBoxArray(dept_boxes, i);
         hypre_BoxArraySetSize(cbox_array, 6);

         hypre_CopyBox(hypre_BoxArrayBox(boxes, i), rembox);
         cbox_array_size = 0;
         for (d = 0; d < 3; d++)
         {
            if ( (hypre_BoxVolume(rembox)) && (border[d][0]) )
            {
               cbox = hypre_BoxArrayBox(cbox_array, cbox_array_size);
               hypre_CopyBox(rembox, cbox);
               hypre_BoxIMaxD(cbox, d) =
                  hypre_BoxIMinD(cbox, d) + border[d][0] - 1;
               hypre_BoxIMinD(rembox, d) =
                  hypre_BoxIMinD(cbox, d) + border[d][0];
               cbox_array_size++;
            }
            if ( (hypre_BoxVolume(rembox)) && (border[d][1]) )
            {
               cbox = hypre_BoxArrayBox(cbox_array, cbox_array_size);
               hypre_CopyBox(rembox, cbox);
               hypre_BoxIMinD(cbox, d) =
                  hypre_BoxIMaxD(cbox, d) - border[d][1] + 1;
               hypre_BoxIMaxD(rembox, d) =
                  hypre_BoxIMaxD(cbox, d) - border[d][1];
               cbox_array_size++;
            }
         }
         hypre_BoxArraySetSize(cbox_array, cbox_array_size);
      }
int
hypre_SMGRelaxSetupASol( void               *relax_vdata,
                         hypre_StructMatrix *A,
                         hypre_StructVector *b,
                         hypre_StructVector *x           )
{
   hypre_SMGRelaxData   *relax_data = relax_vdata;

   int                   num_spaces    = (relax_data -> num_spaces);
   int                  *space_indices = (relax_data -> space_indices);
   int                  *space_strides = (relax_data -> space_strides);
   hypre_StructVector   *temp_vec      = (relax_data -> temp_vec);

   int                   num_pre_relax   = (relax_data -> num_pre_relax);
   int                   num_post_relax  = (relax_data -> num_post_relax);

   hypre_StructStencil  *stencil       = hypre_StructMatrixStencil(A);     
   hypre_Index          *stencil_shape = hypre_StructStencilShape(stencil);
   int                   stencil_size  = hypre_StructStencilSize(stencil); 
   int                   stencil_dim   = hypre_StructStencilDim(stencil);
                       
   hypre_StructMatrix   *A_sol;
   void                **solve_data;

   hypre_Index           base_index;
   hypre_Index           base_stride;

   int                   num_stencil_indices;
   int                  *stencil_indices;
                       
   int                   i;

   int                   ierr = 0;

   /*----------------------------------------------------------
    * Free up old data before putting new data into structure
    *----------------------------------------------------------*/

   hypre_SMGRelaxDestroyASol(relax_vdata);

   /*----------------------------------------------------------
    * Set up data
    *----------------------------------------------------------*/

   hypre_CopyIndex((relax_data -> base_index),  base_index);
   hypre_CopyIndex((relax_data -> base_stride), base_stride);

   stencil_indices = hypre_TAlloc(int, stencil_size);
   num_stencil_indices = 0;
   for (i = 0; i < stencil_size; i++)
   {
      if (hypre_IndexD(stencil_shape[i], (stencil_dim - 1)) == 0)
      {
         stencil_indices[num_stencil_indices] = i;
         num_stencil_indices++;
      }
   }
   A_sol = hypre_StructMatrixCreateMask(A, num_stencil_indices, stencil_indices);
   hypre_StructStencilDim(hypre_StructMatrixStencil(A_sol)) = stencil_dim - 1;
   hypre_TFree(stencil_indices);

   /* Set up solve_data */
   solve_data    = hypre_TAlloc(void *, num_spaces);

   for (i = 0; i < num_spaces; i++)
   {
      hypre_IndexD(base_index,  (stencil_dim - 1)) = space_indices[i];
      hypre_IndexD(base_stride, (stencil_dim - 1)) = space_strides[i];

      if (stencil_dim > 2)
      {
         solve_data[i] = hypre_SMGCreate(relax_data -> comm);
         hypre_SMGSetNumPreRelax( solve_data[i], num_pre_relax);
         hypre_SMGSetNumPostRelax( solve_data[i], num_post_relax);
         hypre_SMGSetBase(solve_data[i], base_index, base_stride);
         hypre_SMGSetMemoryUse(solve_data[i], (relax_data -> memory_use));
         hypre_SMGSetTol(solve_data[i], 0.0);
         hypre_SMGSetMaxIter(solve_data[i], 1);
         hypre_SMGSetup(solve_data[i], A_sol, temp_vec, x);
      }
      else
      {
         solve_data[i] = hypre_CyclicReductionCreate(relax_data -> comm);
         hypre_CyclicReductionSetBase(solve_data[i], base_index, base_stride);
         hypre_CyclicReductionSetup(solve_data[i], A_sol, temp_vec, x);
      }
   }

   (relax_data -> A_sol)      = A_sol;
   (relax_data -> solve_data) = solve_data;

   (relax_data -> setup_a_sol) = 0;

   return ierr;
}