Esempio n. 1
0
hypre_SStructSendInfoData *
hypre_SStructSendInfo( hypre_StructGrid      *fgrid,
                       hypre_BoxManager      *cboxman,
                       hypre_Index            rfactor )
{
   hypre_SStructSendInfoData *sendinfo_data;

   MPI_Comm                   comm= hypre_SStructVectorComm(fgrid);

   hypre_BoxArray            *grid_boxes;
   hypre_Box                 *grid_box, cbox;
   hypre_Box                 *intersect_box, boxman_entry_box;

   hypre_BoxManEntry        **boxman_entries;
   HYPRE_Int                  nboxman_entries;

   hypre_BoxArrayArray       *send_boxes;
   HYPRE_Int                **send_processes;
   HYPRE_Int                **send_remote_boxnums;

   hypre_Index                ilower, iupper, index;

   HYPRE_Int                  myproc, proc;

   HYPRE_Int                  cnt;
   HYPRE_Int                  i, j;

   hypre_ClearIndex(index); 
   hypre_MPI_Comm_rank(comm, &myproc);

   sendinfo_data= hypre_CTAlloc(hypre_SStructSendInfoData, 1);

   /*------------------------------------------------------------------------
    * Create the structured sendbox patterns. 
    *
    *   send_boxes are obtained by intersecting this proc's fgrid boxes
    *   with cgrid's box_man. Intersecting BoxManEntries not on this proc
    *   will give boxes that we will need to send data to- i.e., we scan
    *   through the boxes of grid and find the processors that own a chunk
    *   of it.
    *------------------------------------------------------------------------*/
   intersect_box = hypre_CTAlloc(hypre_Box, 1);
   grid_boxes   = hypre_StructGridBoxes(fgrid);

   send_boxes= hypre_BoxArrayArrayCreate(hypre_BoxArraySize(grid_boxes));
   send_processes= hypre_CTAlloc(HYPRE_Int *, hypre_BoxArraySize(grid_boxes));
   send_remote_boxnums= hypre_CTAlloc(HYPRE_Int *, hypre_BoxArraySize(grid_boxes));

   hypre_ForBoxI(i, grid_boxes)
   {
       grid_box= hypre_BoxArrayBox(grid_boxes, i);

       /*---------------------------------------------------------------------
        * Find the boxarray that must be sent. BoxManIntersect returns
        * the full extents of the boxes that intersect with the given box.
        * We further need to intersect each box in the list with the given
        * box to determine the actual box that needs to be sent.
        *---------------------------------------------------------------------*/
       hypre_SStructIndexScaleF_C(hypre_BoxIMin(grid_box), index,
                                  rfactor, hypre_BoxIMin(&cbox));
       hypre_SStructIndexScaleF_C(hypre_BoxIMax(grid_box), index,
                                  rfactor, hypre_BoxIMax(&cbox));

       hypre_BoxManIntersect(cboxman, hypre_BoxIMin(&cbox), hypre_BoxIMax(&cbox),
                            &boxman_entries, &nboxman_entries);

       cnt= 0;
       for (j= 0; j< nboxman_entries; j++)
       {
          hypre_SStructBoxManEntryGetProcess(boxman_entries[j], &proc);
          if (proc != myproc)
          {
             cnt++;
          }
       }
       send_processes[i]     = hypre_CTAlloc(HYPRE_Int, cnt);
       send_remote_boxnums[i]= hypre_CTAlloc(HYPRE_Int, cnt);

       cnt= 0;
       for (j= 0; j< nboxman_entries; j++)
       {
          hypre_SStructBoxManEntryGetProcess(boxman_entries[j], &proc);

          /* determine the chunk of the boxman_entries[j] box that is needed */
          hypre_BoxManEntryGetExtents(boxman_entries[j], ilower, iupper);
          hypre_BoxSetExtents(&boxman_entry_box, ilower, iupper);
          hypre_IntersectBoxes(&boxman_entry_box, &cbox, &boxman_entry_box);

          if (proc != myproc)
          {
             send_processes[i][cnt]     = proc;
             hypre_SStructBoxManEntryGetBoxnum(boxman_entries[j], 
                                            &send_remote_boxnums[i][cnt]);
             hypre_AppendBox(&boxman_entry_box, 
                              hypre_BoxArrayArrayBoxArray(send_boxes, i));
             cnt++;
          }
      } 
      hypre_TFree(boxman_entries);
   }  /* hypre_ForBoxI(i, grid_boxes) */ 
Esempio n. 2
0
int
hypre_SStructUMatrixSetBoxValues( hypre_SStructMatrix *matrix,
                                  int                  part,
                                  hypre_Index          ilower,
                                  hypre_Index          iupper,
                                  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_BoxMap         *map;
    hypre_BoxMapEntry   **map_entries;
    int                   nmap_entries;
    hypre_BoxMapEntry   **map_to_entries;
    int                   nmap_to_entries;
    int                   nrows;
    int                  *ncols;
    HYPRE_BigInt         *rows;
    HYPRE_BigInt         *cols;
    double               *ijvalues;
    hypre_Box            *box;
    hypre_Box            *to_box;
    hypre_Box            *map_box;
    hypre_Box            *int_box;
    hypre_Index           index;
    hypre_Index           rs, cs;
    int                   sy, sz;
    HYPRE_BigInt          row_base, col_base;
    int                   val_base;
    int                   e, entry, ii, jj, i, j, k;
    int                   proc, myproc;
    /* GEC1002 the matrix type */
    int                   matrix_type = hypre_SStructMatrixObjectType(matrix);

    box = hypre_BoxCreate();

    /*------------------------------------------
     * all stencil entries
     *------------------------------------------*/

    if (entries[0] < size)
    {
        to_box  = hypre_BoxCreate();
        map_box = hypre_BoxCreate();
        int_box = hypre_BoxCreate();

        hypre_CopyIndex(ilower, hypre_BoxIMin(box));
        hypre_CopyIndex(iupper, hypre_BoxIMax(box));
        /* ZTODO: check that this change fixes multiple-entry problem */
        nrows    = hypre_BoxVolume(box)*nentries;
        ncols    = hypre_CTAlloc(int, nrows);
        for (i = 0; i < nrows; i++)
        {
            ncols[i] = 1;
        }
        rows     = hypre_CTAlloc(HYPRE_BigInt, nrows);
        cols     = hypre_CTAlloc(HYPRE_BigInt, nrows);
        ijvalues = hypre_CTAlloc(double, nrows);

        sy = (hypre_IndexX(iupper) - hypre_IndexX(ilower) + 1);
        sz = (hypre_IndexY(iupper) - hypre_IndexY(ilower) + 1) * sy;

        map = hypre_SStructGridMap(grid, part, var);
        hypre_BoxMapIntersect(map, ilower, iupper, &map_entries, &nmap_entries);

        for (ii = 0; ii < nmap_entries; ii++)
        {
            /* 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_entries[ii], &proc);
                MPI_Comm_rank(hypre_SStructGridComm(grid), &myproc);
                if (proc != myproc)
                {
                    continue;
                }
            }

            /* GEC1002 introducing the strides based on the type of the matrix  */
            hypre_SStructMapEntryGetStrides(map_entries[ii], rs, matrix_type);

            hypre_CopyIndex(ilower, hypre_BoxIMin(box));
            hypre_CopyIndex(iupper, hypre_BoxIMax(box));
            hypre_BoxMapEntryGetExtents(map_entries[ii],
                                        hypre_BoxIMin(map_box),
                                        hypre_BoxIMax(map_box));
            hypre_IntersectBoxes(box, map_box, int_box);
            hypre_CopyBox(int_box, box);

            nrows = 0;
            for (e = 0; e < nentries; e++)
            {
                entry = entries[e];

                hypre_CopyBox(box, to_box);

                offset = shape[entry];
                hypre_BoxIMinX(to_box) += hypre_IndexX(offset);
                hypre_BoxIMinY(to_box) += hypre_IndexY(offset);
                hypre_BoxIMinZ(to_box) += hypre_IndexZ(offset);
                hypre_BoxIMaxX(to_box) += hypre_IndexX(offset);
                hypre_BoxIMaxY(to_box) += hypre_IndexY(offset);
                hypre_BoxIMaxZ(to_box) += hypre_IndexZ(offset);

                map = hypre_SStructGridMap(grid, part, vars[entry]);
                hypre_BoxMapIntersect(map, hypre_BoxIMin(to_box),
                                      hypre_BoxIMax(to_box),
                                      &map_to_entries, &nmap_to_entries );

                for (jj = 0; jj < nmap_to_entries; jj++)
                {

                    /* GEC1002 introducing the strides based on the type of the matrix  */

                    hypre_SStructMapEntryGetStrides(map_to_entries[jj], cs, matrix_type);

                    hypre_BoxMapEntryGetExtents(map_to_entries[jj],
                                                hypre_BoxIMin(map_box),
                                                hypre_BoxIMax(map_box));
                    hypre_IntersectBoxes(to_box, map_box, int_box);

                    hypre_CopyIndex(hypre_BoxIMin(int_box), index);

                    /* GEC1002 introducing the rank based on the type of the matrix  */

                    hypre_SStructMapEntryGetGlobalRank(map_to_entries[jj],
                                                       index, &col_base,matrix_type);

                    hypre_IndexX(index) -= hypre_IndexX(offset);
                    hypre_IndexY(index) -= hypre_IndexY(offset);
                    hypre_IndexZ(index) -= hypre_IndexZ(offset);

                    /* GEC1002 introducing the rank based on the type of the matrix  */

                    hypre_SStructMapEntryGetGlobalRank(map_entries[ii],
                                                       index, &row_base,matrix_type);

                    hypre_IndexX(index) -= hypre_IndexX(ilower);
                    hypre_IndexY(index) -= hypre_IndexY(ilower);
                    hypre_IndexZ(index) -= hypre_IndexZ(ilower);
                    val_base = e + (hypre_IndexX(index) +
                                    hypre_IndexY(index)*sy +
                                    hypre_IndexZ(index)*sz) * nentries;

                    for (k = 0; k < hypre_BoxSizeZ(int_box); k++)
                    {
                        for (j = 0; j < hypre_BoxSizeY(int_box); j++)
                        {
                            for (i = 0; i < hypre_BoxSizeX(int_box); i++)
                            {
                                rows[nrows] = row_base + (HYPRE_BigInt)(i*rs[0] + j*rs[1] + k*rs[2]);
                                cols[nrows] = col_base + (HYPRE_BigInt)(i*cs[0] + j*cs[1] + k*cs[2]);
                                ijvalues[nrows] =
                                    values[val_base + (i + j*sy + k*sz)*nentries];
                                nrows++;
                            }
                        }
                    }
                }

                hypre_TFree(map_to_entries);
            }

            /*------------------------------------------
             * set IJ values one stencil entry at a time
             *------------------------------------------*/

            if (add_to > 0)
            {
                HYPRE_IJMatrixAddToValues(ijmatrix, nrows, ncols,
                                          (const HYPRE_BigInt *) rows,
                                          (const HYPRE_BigInt *) cols,
                                          (const double *) ijvalues);
            }
            else if (add_to > -1)
            {
                HYPRE_IJMatrixSetValues(ijmatrix, nrows, ncols,
                                        (const HYPRE_BigInt *) rows,
                                        (const HYPRE_BigInt *) cols,
                                        (const double *) ijvalues);
            }
            else
            {
                HYPRE_IJMatrixGetValues(ijmatrix, nrows, ncols, rows, cols, values);
            }
        }

        hypre_TFree(map_entries);

        hypre_TFree(ncols);
        hypre_TFree(rows);
        hypre_TFree(cols);
        hypre_TFree(ijvalues);

        hypre_BoxDestroy(to_box);
        hypre_BoxDestroy(map_box);
        hypre_BoxDestroy(int_box);
    }
Esempio n. 3
0
HYPRE_Int
hypre_FacZeroCData( void                 *fac_vdata,
                    hypre_SStructMatrix  *A )
{
    hypre_FACData         *fac_data      =  fac_vdata;

    hypre_SStructGrid     *grid;
    hypre_SStructPGrid    *p_cgrid;

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

    hypre_BoxManager      *fboxman;
    hypre_BoxManEntry    **boxman_entries;
    HYPRE_Int              nboxman_entries;

    hypre_Box              scaled_box;
    hypre_Box              intersect_box;

    hypre_SStructPMatrix  *level_pmatrix;
    hypre_StructStencil   *stencils;
    HYPRE_Int              stencil_size;

    hypre_Index           *refine_factors;
    hypre_Index            temp_index;
    hypre_Index            ilower, iupper;

    HYPRE_Int              max_level     =  fac_data -> max_levels;
    HYPRE_Int             *level_to_part =  fac_data -> level_to_part;

    HYPRE_Int              ndim          =  hypre_SStructMatrixNDim(A);
    HYPRE_Int              part_crse     =  0;
    HYPRE_Int              part_fine     =  1;
    HYPRE_Int              level;
    HYPRE_Int              nvars, var;

    HYPRE_Int              ci, i, j, rem, intersect_size;

    double                *values;

    HYPRE_Int              ierr = 0;

    for (level= max_level; level> 0; level--)
    {
        level_pmatrix = hypre_SStructMatrixPMatrix(fac_data -> A_level[level], part_crse);

        grid          = (fac_data -> grid_level[level]);
        refine_factors= &(fac_data -> refine_factors[level]);

        p_cgrid= hypre_SStructGridPGrid(grid, part_crse);
        nvars  = hypre_SStructPGridNVars(p_cgrid);

        for (var= 0; var< nvars; var++)
        {
            stencils    =  hypre_SStructPMatrixSStencil(level_pmatrix, var, var);
            stencil_size=  hypre_StructStencilSize(stencils);

            /*---------------------------------------------------------------------
             * For each variable, find the underlying boxes for each coarse box.
             *---------------------------------------------------------------------*/
            cgrid        = hypre_SStructPGridSGrid(p_cgrid, var);
            cgrid_boxes  = hypre_StructGridBoxes(cgrid);
            fboxman         = hypre_SStructGridBoxManager(grid, part_fine, var);

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

                hypre_ClearIndex(temp_index);
                hypre_StructMapCoarseToFine(hypre_BoxIMin(cgrid_box), temp_index,
                                            *refine_factors, hypre_BoxIMin(&scaled_box));
                for (i= 0; i< ndim; i++)
                {
                    temp_index[i]= (*refine_factors)[i]-1;
                }
                hypre_StructMapCoarseToFine(hypre_BoxIMax(cgrid_box), temp_index,
                                            *refine_factors, hypre_BoxIMax(&scaled_box));

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

                for (i= 0; i< nboxman_entries; i++)
                {
                    hypre_BoxManEntryGetExtents(boxman_entries[i], ilower, iupper);
                    hypre_BoxSetExtents(&intersect_box, ilower, iupper);
                    hypre_IntersectBoxes(&intersect_box, &scaled_box, &intersect_box);

                    /* adjust the box so that it is divisible by refine_factors */
                    for (j= 0; j< ndim; j++)
                    {
                        rem= hypre_BoxIMin(&intersect_box)[j]%(*refine_factors)[j];
                        if (rem)
                        {
                            hypre_BoxIMin(&intersect_box)[j]+=(*refine_factors)[j] - rem;
                        }
                    }

                    hypre_ClearIndex(temp_index);
                    hypre_StructMapFineToCoarse(hypre_BoxIMin(&intersect_box), temp_index,
                                                *refine_factors, hypre_BoxIMin(&intersect_box));
                    hypre_StructMapFineToCoarse(hypre_BoxIMax(&intersect_box), temp_index,
                                                *refine_factors, hypre_BoxIMax(&intersect_box));

                    intersect_size= hypre_BoxVolume(&intersect_box);
                    if (intersect_size > 0)
                    {
                        /*------------------------------------------------------------
                         * Coarse underlying box found. Now zero off.
                         *------------------------------------------------------------*/
                        values= hypre_CTAlloc(double, intersect_size);

                        for (j= 0; j< stencil_size; j++)
                        {
                            HYPRE_SStructMatrixSetBoxValues(fac_data -> A_level[level],
                                                            part_crse,
                                                            hypre_BoxIMin(&intersect_box),
                                                            hypre_BoxIMax(&intersect_box),
                                                            var, 1, &j, values);

                            HYPRE_SStructMatrixSetBoxValues(A,
                                                            level_to_part[level-1],
                                                            hypre_BoxIMin(&intersect_box),
                                                            hypre_BoxIMax(&intersect_box),
                                                            var, 1, &j, values);
                        }

                        hypre_TFree(values);

                    }  /* if (intersect_size > 0) */
                }     /* for (i= 0; i< nboxman_entries; i++) */

                hypre_TFree(boxman_entries);

            }   /* hypre_ForBoxI(ci, cgrid_boxes) */
        }      /* for (var= 0; var< nvars; var++) */
Esempio n. 4
0
HYPRE_Int
hypre_CreateCommInfoFromStencil( hypre_StructGrid      *grid,
                                 hypre_StructStencil   *stencil,
                                 hypre_CommInfo       **comm_info_ptr )
{
   HYPRE_Int              i,j,k, d, m, s;   

   hypre_BoxArrayArray   *send_boxes;
   hypre_BoxArrayArray   *recv_boxes;

   HYPRE_Int            **send_procs;
   HYPRE_Int            **recv_procs;
   HYPRE_Int            **send_rboxnums;
   HYPRE_Int            **recv_rboxnums;
   hypre_BoxArrayArray   *send_rboxes;
   hypre_BoxArrayArray   *recv_rboxes;

   hypre_BoxArray        *local_boxes;
   HYPRE_Int              num_boxes;

   HYPRE_Int             *local_ids;

   hypre_BoxManager      *boxman;
                       
   hypre_Index           *stencil_shape;
   hypre_IndexRef         stencil_offset;
   hypre_IndexRef         pshift;
                          
   hypre_Box             *box;
   hypre_Box             *hood_box;
   hypre_Box             *grow_box;
   hypre_Box             *extend_box;
   hypre_Box             *int_box;
   hypre_Box             *periodic_box;
   
   HYPRE_Int              stencil_grid[3][3][3];
   HYPRE_Int              grow[3][2];
                       
   hypre_BoxManEntry    **entries;
   hypre_BoxManEntry     *entry;
   
   HYPRE_Int              num_entries;
   hypre_BoxArray        *neighbor_boxes = NULL;
   HYPRE_Int             *neighbor_procs = NULL;
   HYPRE_Int             *neighbor_ids = NULL;
   HYPRE_Int             *neighbor_shifts = NULL;
   HYPRE_Int              neighbor_count;
   HYPRE_Int              neighbor_alloc;

   hypre_Index            ilower, iupper;

   hypre_BoxArray        *send_box_array;
   hypre_BoxArray        *recv_box_array;
   hypre_BoxArray        *send_rbox_array;
   hypre_BoxArray        *recv_rbox_array;
                       
   hypre_Box            **cboxes;
   hypre_Box             *cboxes_mem;
   HYPRE_Int             *cboxes_neighbor_location;
   HYPRE_Int              num_cboxes, cbox_alloc;
                       
   HYPRE_Int              istart[3], istop[3];
   HYPRE_Int              sgindex[3];               

   HYPRE_Int              num_periods, loc, box_id, id, proc_id;
   HYPRE_Int              myid;
   
   MPI_Comm               comm;

   /*------------------------------------------------------
    * Initializations
    *------------------------------------------------------*/

   local_boxes  = hypre_StructGridBoxes(grid);
   local_ids    = hypre_StructGridIDs(grid);
   num_boxes    = hypre_BoxArraySize(local_boxes);
   num_periods  = hypre_StructGridNumPeriods(grid);
   
   boxman    = hypre_StructGridBoxMan(grid);
   comm      =  hypre_StructGridComm(grid);
   
   hypre_MPI_Comm_rank(comm, &myid);
  
   for (k = 0; k < 3; k++)
   {
      for (j = 0; j < 3; j++)
      {
         for (i = 0; i < 3; i++)
         {
            stencil_grid[i][j][k] = 0;
         }
      }
   }

   /*------------------------------------------------------
    * Compute the "grow" information from the stencil
    *------------------------------------------------------*/

   stencil_shape = hypre_StructStencilShape(stencil);

   for (d = 0; d < 3; d++)
   {
      grow[d][0] = 0;
      grow[d][1] = 0;
   }

   for (s = 0; s < hypre_StructStencilSize(stencil); s++)
   {
      stencil_offset = stencil_shape[s];

      for (d = 0; d < 3; d++)
      {
         m = stencil_offset[d];

         istart[d] = 1;
         istop[d]  = 1;

         if (m < 0)
         {
            istart[d] = 0;
            grow[d][0] = hypre_max(grow[d][0], -m);
         }
         else if (m > 0)
         {
            istop[d] = 2;
            grow[d][1] = hypre_max(grow[d][1],  m);
         }
      }

      /* update stencil grid from the grow_stencil */
      for (k = istart[2]; k <= istop[2]; k++)
      {
         for (j = istart[1]; j <= istop[1]; j++)
         {
            for (i = istart[0]; i <= istop[0]; i++)
            {
               stencil_grid[i][j][k] = 1;
            }
         }
      }
   }

   /*------------------------------------------------------
    * Compute send/recv boxes and procs for each local box
    *------------------------------------------------------*/

   /* initialize: for each local box, we create an array of send/recv info */

   send_boxes = hypre_BoxArrayArrayCreate(num_boxes);
   recv_boxes = hypre_BoxArrayArrayCreate(num_boxes);
   send_procs = hypre_CTAlloc(HYPRE_Int *, num_boxes);
   recv_procs = hypre_CTAlloc(HYPRE_Int *, num_boxes);

   /* Remote boxnums and boxes describe data on the opposing processor, so some
      shifting of boxes is needed below for periodic neighbor boxes.  Remote box
      info is also needed for receives to allow for reverse communication. */
   send_rboxnums = hypre_CTAlloc(HYPRE_Int *, num_boxes);
   send_rboxes   = hypre_BoxArrayArrayCreate(num_boxes);
   recv_rboxnums = hypre_CTAlloc(HYPRE_Int *, num_boxes);
   recv_rboxes   = hypre_BoxArrayArrayCreate(num_boxes);

   grow_box = hypre_BoxCreate();
   extend_box = hypre_BoxCreate();
   int_box  = hypre_BoxCreate();
   periodic_box =  hypre_BoxCreate();
 
   /* storage we will use and keep track of the neighbors */
   neighbor_alloc = 30; /* initial guess at max size */
   neighbor_boxes = hypre_BoxArrayCreate(neighbor_alloc);
   neighbor_procs = hypre_CTAlloc(HYPRE_Int, neighbor_alloc);
   neighbor_ids = hypre_CTAlloc(HYPRE_Int, neighbor_alloc);
   neighbor_shifts = hypre_CTAlloc(HYPRE_Int, neighbor_alloc);

   /* storage we will use to collect all of the intersected boxes (the send and
      recv regions for box i (this may not be enough in the case of periodic
      boxes, so we will have to check) */
   cbox_alloc =  hypre_BoxManNEntries(boxman);

   cboxes_neighbor_location = hypre_CTAlloc(HYPRE_Int, cbox_alloc);
   cboxes = hypre_CTAlloc(hypre_Box *, cbox_alloc);
   cboxes_mem = hypre_CTAlloc(hypre_Box, cbox_alloc);

   /******* loop through each local box **************/

   for (i = 0; i < num_boxes; i++)
   {
      /* get the box */
      box = hypre_BoxArrayBox(local_boxes, i);
      /* box_id = local_ids[i]; the box id in the Box Manager is the box number,
       * and we use this to find out if a box has intersected with itself */
      box_id = i;
      
      /* grow box local i according to the stencil*/
      hypre_CopyBox(box, grow_box);
      for (d = 0; d < 3; d++)
      {
         hypre_BoxIMinD(grow_box, d) -= grow[d][0];
         hypre_BoxIMaxD(grow_box, d) += grow[d][1];
      }

      /* extend_box - to find the list of potential neighbors, we need to grow
         the local box a bit differently in case, for example, the stencil grows
         in one dimension [0] and not the other [1] */
      hypre_CopyBox(box, extend_box);
      for (d = 0; d < 3; d++)
      { 
         hypre_BoxIMinD(extend_box, d) -= hypre_max(grow[d][0],grow[d][1]);
         hypre_BoxIMaxD(extend_box, d) += hypre_max(grow[d][0],grow[d][1]);
      }

      /*------------------------------------------------
       * Determine the neighbors of box i
       *------------------------------------------------*/
     
      /* Do this by intersecting the extend box with the BoxManager. 
         We must also check for periodic neighbors. */

      neighbor_count = 0;
      hypre_BoxArraySetSize(neighbor_boxes, 0);
      /* shift the box by each period (k=0 is original box) */
      for (k = 0; k < num_periods; k++)
      {
         hypre_CopyBox(extend_box, periodic_box);
         pshift = hypre_StructGridPShift(grid, k);
         hypre_BoxShiftPos(periodic_box, pshift);
         
         /* get the intersections */
         hypre_BoxManIntersect(boxman, hypre_BoxIMin(periodic_box) , 
                               hypre_BoxIMax(periodic_box) , 
                               &entries , &num_entries);
      
         /* note: do we need to remove the intersection with our original box?
            no if periodic, yes if non-periodic (k=0) */ 

         /* unpack entries (first check storage) */
         if (neighbor_count + num_entries > neighbor_alloc)
         {
            neighbor_alloc = neighbor_count + num_entries + 5;
            neighbor_procs = hypre_TReAlloc(neighbor_procs, HYPRE_Int,
                                            neighbor_alloc);
            neighbor_ids = hypre_TReAlloc(neighbor_ids, HYPRE_Int, neighbor_alloc);
            neighbor_shifts = hypre_TReAlloc(neighbor_shifts, HYPRE_Int,
                                             neighbor_alloc);
         }
         /* check storage for the array */
         hypre_BoxArraySetSize(neighbor_boxes, neighbor_count + num_entries);
         /* now unpack */
         for (j = 0; j < num_entries; j++)
         {
            entry = entries[j];
            proc_id = hypre_BoxManEntryProc(entry);        
            id = hypre_BoxManEntryId(entry); 
            /* don't keep box i in the non-periodic case*/  
            if (!k)
            {
               if((myid == proc_id) && (box_id == id))
               {
                  continue;
               }
            }

            hypre_BoxManEntryGetExtents(entry, ilower, iupper);        
            hypre_BoxSetExtents(hypre_BoxArrayBox(neighbor_boxes, neighbor_count),
                                ilower, iupper);
            /* shift the periodic boxes (needs to be the opposite of above) */
            if (k)
            {
               hypre_BoxShiftNeg(
                  hypre_BoxArrayBox(neighbor_boxes, neighbor_count), pshift);
            }
            
            neighbor_procs[neighbor_count] = proc_id;
            neighbor_ids[neighbor_count] = id;
            neighbor_shifts[neighbor_count] = k;
            neighbor_count++;
         }
         hypre_BoxArraySetSize(neighbor_boxes, neighbor_count);

         hypre_TFree(entries);
  
      } /* end of loop through periods k */

      /* Now we have a list of all of the neighbors for box i! */

      /* note: we don't want/need to remove duplicates - they should have
         different intersections (TO DO: put more thought into if there are ever
         any exceptions to this? - the intersection routine already eliminates
         duplicates - so what i mean is eliminating duplicates from multiple
         intersection calls in periodic case)  */  
    
      /*------------------------------------------------
       * Compute recv_box_array for box i
       *------------------------------------------------*/

      /* check size of storage for cboxes */
      /* let's make sure that we have enough storage in case each neighbor
         produces a send/recv region */
      if (neighbor_count > cbox_alloc)
      {
         cbox_alloc = neighbor_count;
         cboxes_neighbor_location = hypre_TReAlloc(cboxes_neighbor_location, 
                                                   HYPRE_Int, cbox_alloc);
         cboxes = hypre_TReAlloc(cboxes, hypre_Box *, cbox_alloc);
         cboxes_mem = hypre_TReAlloc(cboxes_mem, hypre_Box, cbox_alloc);
      }

      /* Loop through each neighbor box.  If the neighbor box intersects the
         grown box i (grown according to our stencil), then the intersection is
         a recv region.  If the neighbor box was shifted to handle periodicity,
         we need to (positive) shift it back. */

      num_cboxes = 0;
      
      for (k = 0; k < neighbor_count; k++)
      {
         hood_box = hypre_BoxArrayBox(neighbor_boxes, k);
         /* check the stencil grid to see if it makes sense to intersect */
         for (d = 0; d < 3; d++)
         {
            sgindex[d] = 1;
               
            s = hypre_BoxIMinD(hood_box, d) - hypre_BoxIMaxD(box, d);
            if (s > 0)
            {
               sgindex[d] = 2;
            }
            s = hypre_BoxIMinD(box, d) - hypre_BoxIMaxD(hood_box, d);
            if (s > 0)
            {
               sgindex[d] = 0;
            }
         }
         /* it makes sense only if we have at least one non-zero entry */   
         if (stencil_grid[sgindex[0]][sgindex[1]][sgindex[2]])
         {
            /* intersect - result is int_box */
            hypre_IntersectBoxes(grow_box, hood_box, int_box);
            /* if we have a positive volume box, this is a recv region */
            if (hypre_BoxVolume(int_box))
            {
               /* keep track of which neighbor: k... */
               cboxes_neighbor_location[num_cboxes] = k;
               cboxes[num_cboxes] = &cboxes_mem[num_cboxes];
               /* keep the intersected box */
               hypre_CopyBox(int_box, cboxes[num_cboxes]);
               num_cboxes++;
            }
         }
      } /* end of loop through each neighbor */

      /* create recv_box_array and recv_procs for box i */
      recv_box_array = hypre_BoxArrayArrayBoxArray(recv_boxes, i);
      hypre_BoxArraySetSize(recv_box_array, num_cboxes);
      recv_procs[i] = hypre_CTAlloc(HYPRE_Int, num_cboxes);
      recv_rboxnums[i] = hypre_CTAlloc(HYPRE_Int, num_cboxes);
      recv_rbox_array = hypre_BoxArrayArrayBoxArray(recv_rboxes, i);
      hypre_BoxArraySetSize(recv_rbox_array, num_cboxes);

      for (m = 0; m < num_cboxes; m++)
      {
         loc = cboxes_neighbor_location[m];
         recv_procs[i][m] = neighbor_procs[loc];
         recv_rboxnums[i][m] = neighbor_ids[loc];
         hypre_CopyBox(cboxes[m], hypre_BoxArrayBox(recv_box_array, m));

         /* if periodic, positive shift before copying to the rbox_array */
         if (neighbor_shifts[loc]) /* periodic if shift != 0 */
         {
            pshift = hypre_StructGridPShift(grid, neighbor_shifts[loc]);
            hypre_BoxShiftPos(cboxes[m], pshift);
         }
         hypre_CopyBox(cboxes[m], hypre_BoxArrayBox(recv_rbox_array, m));

         cboxes[m] = NULL;
      }

      /*------------------------------------------------
       * Compute send_box_array for box i
       *------------------------------------------------*/

      /* Loop through each neighbor box.  If the grown neighbor box intersects
         box i, then the intersection is a send region.  If the neighbor box was
         shifted to handle periodicity, we need to (positive) shift it back. */

      num_cboxes = 0;

      for (k = 0; k < neighbor_count; k++)
      {
         hood_box = hypre_BoxArrayBox(neighbor_boxes, k);
         /* check the stencil grid to see if it makes sense to intersect */
         for (d = 0; d < 3; d++)
         {
            sgindex[d] = 1;
            
            s = hypre_BoxIMinD(box, d) - hypre_BoxIMaxD(hood_box, d);
            if (s > 0)
            {
               sgindex[d] = 2;
            }
            s = hypre_BoxIMinD(hood_box, d) - hypre_BoxIMaxD(box, d);
            if (s > 0)
            {
               sgindex[d] = 0;
            }
         }
         /* it makes sense only if we have at least one non-zero entry */   
         if (stencil_grid[sgindex[0]][sgindex[1]][sgindex[2]])
         {
            /* grow the neighbor box and intersect */
            hypre_CopyBox(hood_box, grow_box);
            for (d = 0; d < 3; d++)
            {
               hypre_BoxIMinD(grow_box, d) -= grow[d][0];
               hypre_BoxIMaxD(grow_box, d) += grow[d][1];
            }
            hypre_IntersectBoxes(box, grow_box, int_box);
            /* if we have a positive volume box, this is a send region */
            if (hypre_BoxVolume(int_box))
            {
               /* keep track of which neighbor: k... */
               cboxes_neighbor_location[num_cboxes] = k;
               cboxes[num_cboxes] = &cboxes_mem[num_cboxes];
               /* keep the intersected box */
               hypre_CopyBox(int_box, cboxes[num_cboxes]);
               num_cboxes++;
            }
         }
      }/* end of loop through neighbors */

      /* create send_box_array and send_procs for box i */
      send_box_array = hypre_BoxArrayArrayBoxArray(send_boxes, i);
      hypre_BoxArraySetSize(send_box_array, num_cboxes);
      send_procs[i] = hypre_CTAlloc(HYPRE_Int, num_cboxes);
      send_rboxnums[i] = hypre_CTAlloc(HYPRE_Int, num_cboxes);
      send_rbox_array = hypre_BoxArrayArrayBoxArray(send_rboxes, i);
      hypre_BoxArraySetSize(send_rbox_array, num_cboxes);

      for (m = 0; m < num_cboxes; m++)
      {
         loc = cboxes_neighbor_location[m];
         send_procs[i][m] = neighbor_procs[loc];
         send_rboxnums[i][m] = neighbor_ids[loc];
         hypre_CopyBox(cboxes[m], hypre_BoxArrayBox(send_box_array, m));

         /* if periodic, positive shift before copying to the rbox_array */
         if (neighbor_shifts[loc]) /* periodic if shift != 0 */
         {
            pshift = hypre_StructGridPShift(grid, neighbor_shifts[loc]);
            hypre_BoxShiftPos(cboxes[m], pshift);
         }
         hypre_CopyBox(cboxes[m], hypre_BoxArrayBox(send_rbox_array, m));

         cboxes[m] = NULL;
      }
   } /* end of loop through each local box */
Esempio n. 5
0
/*--------------------------------------------------------------------------
 * hypre_CF_StenBox: Given a cgrid_box, a fgrid_box, and a stencil_shape,
 * the stencil_shape direction. Returns an empty box if these two boxes
 * are not connected in the stencil_shape direction.
 *--------------------------------------------------------------------------*/
hypre_Box *
hypre_CF_StenBox( hypre_Box              *fgrid_box,
                  hypre_Box              *cgrid_box,
                  hypre_Index             stencil_shape,
                  hypre_Index             rfactors,
                  HYPRE_Int               ndim )
{
   hypre_Box              coarsen_box;
   hypre_Box              contracted_box;
   hypre_Box              extended_box;
   hypre_Box              intersect_box;
   hypre_Box             *stenbox;

   hypre_Box              shift_cbox, shift_ibox;
   hypre_Index            size_cbox, size_ibox;

   hypre_Index            temp_index;
   hypre_Index            shift_index;

   HYPRE_Int              i, remainder, intersect_size;

   hypre_ClearIndex(temp_index);
   stenbox = hypre_BoxCreate();

  /*--------------------------------------------------------------------------
   * Coarsen the fine box, extend it, and shift it to determine if there
   * is a reach between fgrid_box and cgrid_box in the stencil_shape direction.
   * Note: the fine_box may not align as the index rule assumes:
   *  [a_0,a_1,a_2]x[b_0,b_1,b_2], a_i= c_i*rfactors[i]
   *                               b_i= f_i*rfactors[i]+g_i, g_i= rfactors[i]-1.
   * When fine_box does not, then there must be a sibling box. fine_box
   * should be adjusted so that the flooring of the MapFineToCoarse does not
   * introduce extra coarse nodes in the coarsened box. Only the lower bound
   * needs to be adjusted.
   *--------------------------------------------------------------------------*/
   hypre_CopyBox(fgrid_box, &contracted_box);
   for (i= 0; i< ndim; i++)
   {
      remainder= hypre_BoxIMin(&contracted_box)[i] % rfactors[i];
      if (remainder)
      {
          hypre_BoxIMin(&contracted_box)[i]+= rfactors[i] - remainder;
      }
   }

   hypre_StructMapFineToCoarse(hypre_BoxIMin(&contracted_box), temp_index,
                               rfactors, hypre_BoxIMin(&coarsen_box));
   hypre_StructMapFineToCoarse(hypre_BoxIMax(&contracted_box), temp_index,
                               rfactors, hypre_BoxIMax(&coarsen_box));

   hypre_ClearIndex(size_cbox);
   for (i= 0; i< ndim; i++)
   {
      size_cbox[i] = hypre_BoxSizeD(&coarsen_box, i) - 1;
   }

  /*---------------------------------------------------------------------
   * Extend the coarsened fgrid_box by one layer in each direction so
   * that actual cf interface is reached. If only coarsen_box were
   * extended, the actual cf interface may not be reached.
   *---------------------------------------------------------------------*/
   hypre_CopyBox(&coarsen_box, &extended_box);
   /*hypre_StructMapFineToCoarse(hypre_BoxIMin(fgrid_box), temp_index,
                               rfactors, hypre_BoxIMin(&extended_box));
   hypre_StructMapFineToCoarse(hypre_BoxIMax(fgrid_box), temp_index,
                               rfactors, hypre_BoxIMax(&extended_box));*/
   for (i= 0; i< ndim; i++)
   {
      hypre_BoxIMin(&extended_box)[i]-=1;
      hypre_BoxIMax(&extended_box)[i]+=1;
   }

   hypre_IntersectBoxes(&extended_box, cgrid_box, &intersect_box);
   intersect_size= hypre_BoxVolume(&intersect_box);
   if (intersect_size == 0)
   {
       hypre_CopyBox(&intersect_box, stenbox);
       return stenbox;
   }

   hypre_ClearIndex(size_ibox);
   for (i= 0; i< ndim; i++)
   {
      size_ibox[i] = hypre_BoxSizeD(&intersect_box, i) - 1;
   }

  /*---------------------------------------------------------------------
   * To find the box extents that must be loop over, we need to take the
   * "opposite" stencil_shape and shift the coarsen and extended boxes.
   *---------------------------------------------------------------------*/
   hypre_SetIndex(shift_index,
                 -size_ibox[0]*stencil_shape[0],
                 -size_ibox[1]*stencil_shape[1],
                 -size_ibox[2]*stencil_shape[2]);
   hypre_AddIndex(shift_index, hypre_BoxIMin(&intersect_box), hypre_BoxIMin(&shift_ibox));
   hypre_AddIndex(shift_index, hypre_BoxIMax(&intersect_box), hypre_BoxIMax(&shift_ibox));
   hypre_IntersectBoxes(&shift_ibox, &intersect_box, &shift_ibox);

   hypre_SetIndex(shift_index,
                 -size_cbox[0]*stencil_shape[0],
                 -size_cbox[1]*stencil_shape[1],
                 -size_cbox[2]*stencil_shape[2]);
   hypre_AddIndex(shift_index, hypre_BoxIMin(&coarsen_box), hypre_BoxIMin(&shift_cbox));
   hypre_AddIndex(shift_index, hypre_BoxIMax(&coarsen_box), hypre_BoxIMax(&shift_cbox));
   hypre_IntersectBoxes(&shift_cbox, &coarsen_box, &shift_cbox);

  /*---------------------------------------------------------------------
   * shift_ibox & shift_cbox will contain the loop extents. Shifting
   * shift_cbox by -stencil_shape and then intersecting with shift_ibox
   * gives the exact extents.
   *---------------------------------------------------------------------*/
   hypre_SetIndex(shift_index, -stencil_shape[0], -stencil_shape[1], -stencil_shape[2]);
   hypre_AddIndex(shift_index, hypre_BoxIMin(&shift_cbox), hypre_BoxIMin(&shift_cbox));
   hypre_AddIndex(shift_index, hypre_BoxIMax(&shift_cbox), hypre_BoxIMax(&shift_cbox));
   hypre_IntersectBoxes(&shift_cbox, &shift_ibox, stenbox);

   return stenbox;
}