Exemple #1
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 */
Exemple #2
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++) */
HYPRE_Int
hypre_SMGResidualSetup( void               *residual_vdata,
                        hypre_StructMatrix *A,
                        hypre_StructVector *x,
                        hypre_StructVector *b,
                        hypre_StructVector *r              )
{
   HYPRE_Int ierr;

   hypre_SMGResidualData  *residual_data = residual_vdata;

   hypre_IndexRef          base_index  = (residual_data -> base_index);
   hypre_IndexRef          base_stride = (residual_data -> base_stride);
   hypre_Index             unit_stride;

   hypre_StructGrid       *grid;
   hypre_StructStencil    *stencil;
                       
   hypre_BoxArray         *base_points;
   hypre_ComputeInfo      *compute_info;
   hypre_ComputePkg       *compute_pkg;

   /*----------------------------------------------------------
    * Set up base points and the compute package
    *----------------------------------------------------------*/

   grid    = hypre_StructMatrixGrid(A);
   stencil = hypre_StructMatrixStencil(A);

   hypre_SetIndex(unit_stride, 1, 1, 1);

   base_points = hypre_BoxArrayDuplicate(hypre_StructGridBoxes(grid));
   hypre_ProjectBoxArray(base_points, base_index, base_stride);

   hypre_CreateComputeInfo(grid, stencil, &compute_info);
   hypre_ComputeInfoProjectComp(compute_info, base_index, base_stride);
   hypre_ComputePkgCreate(compute_info, hypre_StructVectorDataSpace(x), 1,
                          grid, &compute_pkg);

   /*----------------------------------------------------------
    * Set up the residual data structure
    *----------------------------------------------------------*/

   (residual_data -> A)           = hypre_StructMatrixRef(A);
   (residual_data -> x)           = hypre_StructVectorRef(x);
   (residual_data -> b)           = hypre_StructVectorRef(b);
   (residual_data -> r)           = hypre_StructVectorRef(r);
   (residual_data -> base_points) = base_points;
   (residual_data -> compute_pkg) = compute_pkg;

   /*-----------------------------------------------------
    * Compute flops
    *-----------------------------------------------------*/

   (residual_data -> flops) =
      (hypre_StructMatrixGlobalSize(A) + hypre_StructVectorGlobalSize(x)) /
      (hypre_IndexX(base_stride) *
       hypre_IndexY(base_stride) *
       hypre_IndexZ(base_stride)  );

   return ierr;
}
Exemple #4
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) */ 
Exemple #5
0
int
hypre_SemiInterp( void               *interp_vdata,
                  hypre_StructMatrix *P,
                  hypre_StructVector *xc,
                  hypre_StructVector *e            )
{
   int ierr = 0;

   hypre_SemiInterpData   *interp_data = interp_vdata;

   int                     P_stored_as_transpose;
   hypre_ComputePkg       *compute_pkg;
   hypre_IndexRef          cindex;
   hypre_IndexRef          findex;
   hypre_IndexRef          stride;

   hypre_StructGrid       *fgrid;
   int                    *fgrid_ids;
   hypre_StructGrid       *cgrid;
   hypre_BoxArray         *cgrid_boxes;
   int                    *cgrid_ids;

   hypre_CommHandle       *comm_handle;
                       
   hypre_BoxArrayArray    *compute_box_aa;
   hypre_BoxArray         *compute_box_a;
   hypre_Box              *compute_box;
                       
   hypre_Box              *P_dbox;
   hypre_Box              *xc_dbox;
   hypre_Box              *e_dbox;
                       
   int                     Pi;
   int                     xci;
   int                     ei;
                         
   double                 *Pp0, *Pp1;
   double                 *xcp;
   double                 *ep, *ep0, *ep1;
                       
   hypre_Index             loop_size;
   hypre_Index             start;
   hypre_Index             startc;
   hypre_Index             stridec;
                       
   hypre_StructStencil    *stencil;
   hypre_Index            *stencil_shape;

   int                     compute_i, fi, ci, j;
   int                     loopi, loopj, loopk;

   /*-----------------------------------------------------------------------
    * Initialize some things
    *-----------------------------------------------------------------------*/

   hypre_BeginTiming(interp_data -> time_index);

   P_stored_as_transpose = (interp_data -> P_stored_as_transpose);
   compute_pkg   = (interp_data -> compute_pkg);
   cindex        = (interp_data -> cindex);
   findex        = (interp_data -> findex);
   stride        = (interp_data -> stride);

   stencil       = hypre_StructMatrixStencil(P);
   stencil_shape = hypre_StructStencilShape(stencil);

   hypre_SetIndex(stridec, 1, 1, 1);

   /*-----------------------------------------------------------------------
    * Compute e at coarse points (injection)
    *-----------------------------------------------------------------------*/

   fgrid = hypre_StructVectorGrid(e);
   fgrid_ids = hypre_StructGridIDs(fgrid);
   cgrid = hypre_StructVectorGrid(xc);
   cgrid_boxes = hypre_StructGridBoxes(cgrid);
   cgrid_ids = hypre_StructGridIDs(cgrid);

   fi = 0;
   hypre_ForBoxI(ci, cgrid_boxes)
      {
         while (fgrid_ids[fi] != cgrid_ids[ci])
         {
            fi++;
         }

         compute_box = hypre_BoxArrayBox(cgrid_boxes, ci);

         hypre_CopyIndex(hypre_BoxIMin(compute_box), startc);
         hypre_StructMapCoarseToFine(startc, cindex, stride, start);

         e_dbox  = hypre_BoxArrayBox(hypre_StructVectorDataSpace(e), fi);
         xc_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(xc), ci);

         ep  = hypre_StructVectorBoxData(e, fi);
         xcp = hypre_StructVectorBoxData(xc, ci);

         hypre_BoxGetSize(compute_box, loop_size);

         hypre_BoxLoop2Begin(loop_size,
                             e_dbox, start, stride, ei,
                             xc_dbox, startc, stridec, xci);
#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,ei,xci
#include "hypre_box_smp_forloop.h"
         hypre_BoxLoop2For(loopi, loopj, loopk, ei, xci)
            {
               ep[ei] = xcp[xci];
            }
         hypre_BoxLoop2End(ei, xci);
      }

   /*-----------------------------------------------------------------------
    * Compute e at fine points
    *-----------------------------------------------------------------------*/

   for (compute_i = 0; compute_i < 2; compute_i++)
   {
      switch(compute_i)
      {
         case 0:
         {
            ep = hypre_StructVectorData(e);
            hypre_InitializeIndtComputations(compute_pkg, ep, &comm_handle);
            compute_box_aa = hypre_ComputePkgIndtBoxes(compute_pkg);
         }
         break;

         case 1:
         {
            hypre_FinalizeIndtComputations(comm_handle);
            compute_box_aa = hypre_ComputePkgDeptBoxes(compute_pkg);
         }
         break;
      }

      hypre_ForBoxArrayI(fi, compute_box_aa)
         {
            compute_box_a = hypre_BoxArrayArrayBoxArray(compute_box_aa, fi);

            P_dbox = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(P), fi);
            e_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(e), fi);

            if (P_stored_as_transpose)
            {
               Pp0 = hypre_StructMatrixBoxData(P, fi, 1);
               Pp1 = hypre_StructMatrixBoxData(P, fi, 0) -
                  hypre_BoxOffsetDistance(P_dbox, stencil_shape[0]);
            }
            else
            {
               Pp0 = hypre_StructMatrixBoxData(P, fi, 0);
               Pp1 = hypre_StructMatrixBoxData(P, fi, 1);
            }
            ep  = hypre_StructVectorBoxData(e, fi);
            ep0 = ep + hypre_BoxOffsetDistance(e_dbox, stencil_shape[0]);
            ep1 = ep + hypre_BoxOffsetDistance(e_dbox, stencil_shape[1]);

            hypre_ForBoxI(j, compute_box_a)
               {
                  compute_box = hypre_BoxArrayBox(compute_box_a, j);

                  hypre_CopyIndex(hypre_BoxIMin(compute_box), start);
                  hypre_StructMapFineToCoarse(start, findex, stride, startc);

                  hypre_BoxGetStrideSize(compute_box, stride, loop_size);

                  hypre_BoxLoop2Begin(loop_size,
                                      P_dbox, startc, stridec, Pi,
                                      e_dbox, start, stride, ei);
#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,Pi,ei
#include "hypre_box_smp_forloop.h"
                  hypre_BoxLoop2For(loopi, loopj, loopk, Pi, ei)
                     {
                        ep[ei] =  (Pp0[Pi] * ep0[ei] +
                                   Pp1[Pi] * ep1[ei]);
                     }
                  hypre_BoxLoop2End(Pi, ei);
               }
         }
Exemple #6
0
int
hypre_SStructUMatrixInitialize( hypre_SStructMatrix *matrix )
{
    HYPRE_IJMatrix          ijmatrix   = hypre_SStructMatrixIJMatrix(matrix);
    hypre_SStructGraph     *graph      = hypre_SStructMatrixGraph(matrix);
    hypre_SStructGrid      *grid       = hypre_SStructGraphGrid(graph);
    int                     nparts     = hypre_SStructGraphNParts(graph);
    hypre_SStructPGrid    **pgrids     = hypre_SStructGraphPGrids(graph);
    hypre_SStructStencil ***stencils   = hypre_SStructGraphStencils(graph);
    int                     nUventries = hypre_SStructGraphNUVEntries(graph);
    int                    *iUventries = hypre_SStructGraphIUVEntries(graph);
    hypre_SStructUVEntry  **Uventries  = hypre_SStructGraphUVEntries(graph);
    int                   **nvneighbors = hypre_SStructGridNVNeighbors(grid);
    hypre_StructGrid       *sgrid;
    hypre_SStructStencil   *stencil;
    int                    *split;
    int                     nvars;
    int                     nrows, nnzs ;
    int                     part, var, entry, i, j, k,m,b;
    int                    *row_sizes;
    int                     max_row_size;

    int                    matrix_type = hypre_SStructMatrixObjectType(matrix);

    hypre_Box              *gridbox;
    hypre_Box              *loopbox;
    hypre_Box              *ghostbox;
    hypre_BoxArray         *boxes;
    int                    *num_ghost;


    HYPRE_IJMatrixSetObjectType(ijmatrix, HYPRE_PARCSR);

    /* GEC1002 the ghlocalsize is used to set the number of rows   */

    if (matrix_type == HYPRE_PARCSR)
    {
        nrows = hypre_SStructGridLocalSize(grid);
    }
    if (matrix_type == HYPRE_SSTRUCT || matrix_type == HYPRE_STRUCT)
    {
        nrows = hypre_SStructGridGhlocalSize(grid) ;
    }

    /* set row sizes */
    m = 0;
    row_sizes = hypre_CTAlloc(int, nrows);
    max_row_size = 0;
    for (part = 0; part < nparts; part++)
    {
        nvars = hypre_SStructPGridNVars(pgrids[part]);
        for (var = 0; var < nvars; var++)
        {
            sgrid   = hypre_SStructPGridSGrid(pgrids[part], var);

            stencil = stencils[part][var];
            split   = hypre_SStructMatrixSplit(matrix, part, var);
            nnzs = 0;
            for (entry = 0; entry < hypre_SStructStencilSize(stencil); entry++)
            {
                if (split[entry] == -1)
                {
                    nnzs++;
                }
            }
#if 0
            /* TODO: For now, assume stencil is full/complete */
            if (hypre_SStructMatrixSymmetric(matrix))
            {
                nnzs = 2*nnzs - 1;
            }
#endif

            /**************/

            boxes = hypre_StructGridBoxes(sgrid) ;
            num_ghost = hypre_StructGridNumGhost(sgrid);
            for (b = 0; b < hypre_BoxArraySize(boxes); b++)
            {
                gridbox = hypre_BoxArrayBox(boxes, b);
                ghostbox = hypre_BoxCreate();
                loopbox  = hypre_BoxCreate();
                hypre_CopyBox(gridbox,ghostbox);
                hypre_BoxExpand(ghostbox,num_ghost);

                if (matrix_type == HYPRE_SSTRUCT || matrix_type == HYPRE_STRUCT)
                {
                    hypre_CopyBox(ghostbox,loopbox);
                }
                if (matrix_type == HYPRE_PARCSR)
                {
                    hypre_CopyBox(gridbox,loopbox);
                }

                for (k = hypre_BoxIMinZ(loopbox); k <= hypre_BoxIMaxZ(loopbox); k++)
                {
                    for (j = hypre_BoxIMinY(loopbox); j <= hypre_BoxIMaxY(loopbox); j++)
                    {
                        for (i = hypre_BoxIMinX(loopbox); i <= hypre_BoxIMaxX(loopbox); i++)
                        {
                            if (   ( ( i>=hypre_BoxIMinX(gridbox) )
                                     &&   ( j>=hypre_BoxIMinY(gridbox) ) )
                                    &&   ( k>=hypre_BoxIMinZ(gridbox) ) )
                            {
                                if (  ( ( i<=hypre_BoxIMaxX(gridbox) )
                                        && ( j<=hypre_BoxIMaxY(gridbox) ) )
                                        && ( k<=hypre_BoxIMaxZ(gridbox) ) )
                                {
                                    row_sizes[m] = nnzs;
                                    max_row_size = hypre_max(max_row_size, row_sizes[m]);
                                }
                            }
                            m++;
                        }
                    }
                }
                hypre_BoxDestroy(ghostbox);
                hypre_BoxDestroy(loopbox);
            }


            if (nvneighbors[part][var])
            {
                max_row_size = hypre_max(max_row_size,
                                         hypre_SStructStencilSize(stencil));
            }


            /*********************/
        }
    }

    /* GEC0902 essentially for each UVentry we figure out how many extra columns
     * we need to add to the rowsizes                                   */

    for (entry = 0; entry < nUventries; entry++)
    {
        i = iUventries[entry];
        row_sizes[i] += hypre_SStructUVEntryNUEntries(Uventries[i]);
        max_row_size = hypre_max(max_row_size, row_sizes[i]);
    }

    /* ZTODO: Update row_sizes based on neighbor off-part couplings */
    HYPRE_IJMatrixSetRowSizes (ijmatrix, (const int *) row_sizes);

    hypre_TFree(row_sizes);
    hypre_SStructMatrixTmpColCoords(matrix) =
        hypre_CTAlloc(HYPRE_BigInt, max_row_size);
    hypre_SStructMatrixTmpCoeffs(matrix) =
        hypre_CTAlloc(double, max_row_size);

    /* GEC1002 at this point the processor has the partitioning (creation of ij) */

    HYPRE_IJMatrixInitialize(ijmatrix);

    return hypre_error_flag;
}
Exemple #7
0
HYPRE_Int
hypre_CreateComputeInfo( hypre_StructGrid      *grid,
                         hypre_StructStencil   *stencil,
                         hypre_ComputeInfo    **compute_info_ptr )
{
   HYPRE_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;

   HYPRE_Int                i;

#ifdef HYPRE_OVERLAP_COMM_COMP
   hypre_Box               *rembox;
   hypre_Index             *stencil_shape;
   HYPRE_Int                border[3][2] = {{0, 0}, {0, 0}, {0, 0}};
   HYPRE_Int                cbox_array_size;
   HYPRE_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);
      }
Exemple #8
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);
   }
/*--------------------------------------------------------------------------
 * hypre_SStructSharedDOF_ParcsrMatRowsComm
 *   Given a sstruct_grid & parcsr matrix with rows corresponding to the
 *   sstruct_grid, determine and extract the rows that must be communicated.
 *   These rows are for shared dof that geometrically lie on processor 
 *   boundaries but internally are stored on one processor.
 *   Algo:
 *       for each cellbox
 *         RECVs:
 *          i)  stretch the cellbox to the variable box
 *          ii) in the appropriate (dof-dependent) direction, take the
 *              boundary and boxman_intersect to extract boxmanentries
 *              that contain these boundary edges.
 *          iii)loop over the boxmanentries and see if they belong
 *              on this proc or another proc
 *                 a) if belong on another proc, these are the recvs:
 *                    count and prepare the communication buffers and
 *                    values.
 *          
 *         SENDs:
 *          i)  form layer of cells that is one layer off cellbox
 *              (stretches in the appropriate direction)
 *          ii) boxman_intersect with the cellgrid boxman
 *          iii)loop over the boxmanentries and see if they belong
 *              on this proc or another proc
 *                 a) if belong on another proc, these are the sends:
 *                    count and prepare the communication buffers and
 *                    values.
 *
 * Note: For the recv data, the dof can come from only one processor.
 *       For the send data, the dof can go to more than one processor 
 *       (the same dof is on the boundary of several cells).
 *--------------------------------------------------------------------------*/
HYPRE_Int
hypre_SStructSharedDOF_ParcsrMatRowsComm( hypre_SStructGrid    *grid,
                                          hypre_ParCSRMatrix   *A,
                                          HYPRE_Int            *num_offprocrows_ptr,
                                          hypre_MaxwellOffProcRow ***OffProcRows_ptr)
{
   MPI_Comm             A_comm= hypre_ParCSRMatrixComm(A);
   MPI_Comm          grid_comm= hypre_SStructGridComm(grid);

   HYPRE_Int       matrix_type= HYPRE_PARCSR;

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

   hypre_SStructGrid     *cell_ssgrid;

   hypre_SStructPGrid    *pgrid;
   hypre_StructGrid      *cellgrid;
   hypre_BoxArray        *cellboxes;
   hypre_Box             *box, *cellbox, vbox, boxman_entry_box;

   hypre_Index            loop_size, start;
   HYPRE_Int              loopi, loopj, loopk;
   HYPRE_Int              start_rank, end_rank, rank; 

   HYPRE_Int              i, j, k, m, n, t, part, var, nvars;

   HYPRE_SStructVariable *vartypes;
   HYPRE_Int              nbdry_slabs;
   hypre_BoxArray        *recv_slabs, *send_slabs;
   hypre_Index            varoffset;

   hypre_BoxManager     **boxmans, *cell_boxman;
   hypre_BoxManEntry    **boxman_entries, *entry;
   HYPRE_Int              nboxman_entries;

   hypre_Index            ishift, jshift, kshift, zero_index;
   hypre_Index            ilower, iupper, index;

   HYPRE_Int              proc, nprocs, myproc;
   HYPRE_Int             *SendToProcs, *RecvFromProcs;
   HYPRE_Int            **send_RowsNcols;       /* buffer for rows & ncols */
   HYPRE_Int             *send_RowsNcols_alloc; 
   HYPRE_Int             *send_ColsData_alloc;
   HYPRE_Int             *tot_nsendRowsNcols, *tot_sendColsData;
   double               **vals;  /* buffer for cols & data */

   HYPRE_Int             *col_inds;
   double                *values;

   hypre_MPI_Request           *requests;
   hypre_MPI_Status            *status;
   HYPRE_Int            **rbuffer_RowsNcols;
   double               **rbuffer_ColsData;
   HYPRE_Int              num_sends, num_recvs;

   hypre_MaxwellOffProcRow **OffProcRows;
   HYPRE_Int                *starts;

   HYPRE_Int              ierr= 0;

   hypre_MPI_Comm_rank(A_comm, &myproc);
   hypre_MPI_Comm_size(grid_comm, &nprocs);

   start_rank= hypre_ParCSRMatrixFirstRowIndex(A);
   end_rank  = hypre_ParCSRMatrixLastRowIndex(A);

   hypre_SetIndex(ishift, 1, 0, 0);
   hypre_SetIndex(jshift, 0, 1, 0);
   hypre_SetIndex(kshift, 0, 0, 1);
   hypre_SetIndex(zero_index, 0, 0, 0);

  /* need a cellgrid boxman to determine the send boxes -> only the cell dofs
     are unique so a boxman intersect can be used to get the edges that
     must be sent. */
   HYPRE_SStructGridCreate(grid_comm, ndim, nparts, &cell_ssgrid);
   vartypes= hypre_CTAlloc(HYPRE_SStructVariable, 1);
   vartypes[0]= HYPRE_SSTRUCT_VARIABLE_CELL;

   for (i= 0; i< nparts; i++)
   {
      pgrid= hypre_SStructGridPGrid(grid, i);
      cellgrid= hypre_SStructPGridCellSGrid(pgrid);

      cellboxes= hypre_StructGridBoxes(cellgrid);
      hypre_ForBoxI(j, cellboxes)
      {
         box= hypre_BoxArrayBox(cellboxes, j);
         HYPRE_SStructGridSetExtents(cell_ssgrid, i,
                                     hypre_BoxIMin(box), hypre_BoxIMax(box));
      }
      HYPRE_SStructGridSetVariables(cell_ssgrid, i, 1, vartypes);
   }
Exemple #10
0
HYPRE_Int 
HYPRE_StructDiagScale( HYPRE_StructSolver solver,
                       HYPRE_StructMatrix HA,
                       HYPRE_StructVector Hy,
                       HYPRE_StructVector Hx      )
{
   hypre_StructMatrix   *A = (hypre_StructMatrix *) HA;
   hypre_StructVector   *y = (hypre_StructVector *) Hy;
   hypre_StructVector   *x = (hypre_StructVector *) Hx;

   hypre_BoxArray       *boxes;
   hypre_Box            *box;

   hypre_Box            *A_data_box;
   hypre_Box            *y_data_box;
   hypre_Box            *x_data_box;
                     
   double               *Ap;
   double               *yp;
   double               *xp;
                       
   HYPRE_Int             Ai;
   HYPRE_Int             yi;
   HYPRE_Int             xi;
                     
   hypre_Index           index;
   hypre_IndexRef        start;
   hypre_Index           stride;
   hypre_Index           loop_size;
                     
   HYPRE_Int             i;

   /* x = D^{-1} y */
   hypre_SetIndex(stride, 1, 1, 1);
   boxes = hypre_StructGridBoxes(hypre_StructMatrixGrid(A));
   hypre_ForBoxI(i, boxes)
   {
      box = hypre_BoxArrayBox(boxes, i);

      A_data_box = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(A), i);
      x_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(x), i);
      y_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(y), i);

      hypre_SetIndex(index, 0, 0, 0);
      Ap = hypre_StructMatrixExtractPointerByIndex(A, i, index);
      xp = hypre_StructVectorBoxData(x, i);
      yp = hypre_StructVectorBoxData(y, i);

      start  = hypre_BoxIMin(box);

      hypre_BoxGetSize(box, loop_size);

      hypre_BoxLoop3Begin(hypre_StructVectorDim(Hx), loop_size,
                          A_data_box, start, stride, Ai,
                          x_data_box, start, stride, xi,
                          y_data_box, start, stride, yi);
#ifdef HYPRE_USING_OPENMP
#pragma omp parallel for private(HYPRE_BOX_PRIVATE,yi,xi,Ai) HYPRE_SMP_SCHEDULE
#endif
      hypre_BoxLoop3For(Ai, xi, yi)
      {
         xp[xi] = yp[yi] / Ap[Ai];
      }
      hypre_BoxLoop3End(Ai, xi, yi);
   }
Exemple #11
0
   HYPRE_SStructGridAssemble(edge_grid);

   /* CREATE IJ_MATRICES- need to find the size of each one. Notice that the row
      and col ranks of these matrices can be created using only grid information. 
      Grab the first part, first variable, first box, and lower index (lower rank);
      Grab the last part, last variable, last box, and upper index (upper rank). */
 
   /* Grad: node(col) -> edge(row). Same for 2-d and 3-d */
   /* lower rank */
   part= 0;
   i   = 0;

   hypre_SStructGridBoxProcFindBoxManEntry(edge_grid, part, 0, i, myproc, &entry);
   pgrid   = hypre_SStructGridPGrid(edge_grid, part);
   var_grid= hypre_SStructPGridSGrid(pgrid, 0);
   boxes   = hypre_StructGridBoxes(var_grid);
   box     = hypre_BoxArrayBox(boxes, 0);
   hypre_SStructBoxManEntryGetGlobalCSRank(entry, hypre_BoxIMin(box), &ilower);

   hypre_SStructGridBoxProcFindBoxManEntry(node_grid, part, 0, i, myproc, &entry);
   pgrid   = hypre_SStructGridPGrid(node_grid, part);
   var_grid= hypre_SStructPGridSGrid(pgrid, 0);
   boxes   = hypre_StructGridBoxes(var_grid);
   box     = hypre_BoxArrayBox(boxes, 0);
   hypre_SStructBoxManEntryGetGlobalCSRank(entry, hypre_BoxIMin(box), &jlower);

   /* upper rank */
   part= nparts-1;

   pgrid   = hypre_SStructGridPGrid(edge_grid, part);
   nvars   = hypre_SStructPGridNVars(pgrid);
int 
HYPRE_StructDiagScale( HYPRE_StructSolver solver,
                       HYPRE_StructMatrix HA,
                       HYPRE_StructVector Hy,
                       HYPRE_StructVector Hx      )
{
   hypre_StructMatrix   *A = (hypre_StructMatrix *) HA;
   hypre_StructVector   *y = (hypre_StructVector *) Hy;
   hypre_StructVector   *x = (hypre_StructVector *) Hx;

   hypre_BoxArray       *boxes;
   hypre_Box            *box;

   hypre_Box            *A_data_box;
   hypre_Box            *y_data_box;
   hypre_Box            *x_data_box;
                     
   double               *Ap;
   double               *yp;
   double               *xp;
                       
   int                   Ai;
   int                   yi;
   int                   xi;
                     
   hypre_Index           index;
   hypre_IndexRef        start;
   hypre_Index           stride;
   hypre_Index           loop_size;
                     
   int                   i;
   int                   loopi, loopj, loopk;

   int                   ierr = 0;
  
   /* x = D^{-1} y */
   hypre_SetIndex(stride, 1, 1, 1);
   boxes = hypre_StructGridBoxes(hypre_StructMatrixGrid(A));
   hypre_ForBoxI(i, boxes)
      {
         box = hypre_BoxArrayBox(boxes, i);

         A_data_box = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(A), i);
         x_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(x), i);
         y_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(y), i);

         hypre_SetIndex(index, 0, 0, 0);
         Ap = hypre_StructMatrixExtractPointerByIndex(A, i, index);
         xp = hypre_StructVectorBoxData(x, i);
         yp = hypre_StructVectorBoxData(y, i);

         start  = hypre_BoxIMin(box);

         hypre_BoxGetSize(box, loop_size);

         hypre_BoxLoop3Begin(loop_size,
                             A_data_box, start, stride, Ai,
                             x_data_box, start, stride, xi,
                             y_data_box, start, stride, yi);
#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,yi,xi,Ai
#include "hypre_box_smp_forloop.h"
         hypre_BoxLoop3For(loopi, loopj, loopk, Ai, xi, yi)
            {
               xp[xi] = yp[yi] / Ap[Ai];
            }
         hypre_BoxLoop3End(Ai, xi, yi);
      }
int
hypre_SemiRestrict( void               *restrict_vdata,
                    hypre_StructMatrix *R,
                    hypre_StructVector *r,
                    hypre_StructVector *rc             )
{
   int ierr = 0;

   hypre_SemiRestrictData *restrict_data = (hypre_SemiRestrictData *)restrict_vdata;

   int                     R_stored_as_transpose;
   hypre_ComputePkg       *compute_pkg;
   hypre_IndexRef          cindex;
   hypre_IndexRef          stride;

   hypre_StructGrid       *fgrid;
   int                    *fgrid_ids;
   hypre_StructGrid       *cgrid;
   hypre_BoxArray         *cgrid_boxes;
   int                    *cgrid_ids;

   hypre_CommHandle       *comm_handle;
                       
   hypre_BoxArrayArray    *compute_box_aa;
   hypre_BoxArray         *compute_box_a;
   hypre_Box              *compute_box;
                       
   hypre_Box              *R_dbox;
   hypre_Box              *r_dbox;
   hypre_Box              *rc_dbox;
                       
   int                     Ri;
   int                     ri;
   int                     rci;
                         
   double                 *Rp0, *Rp1;
   double                 *rp, *rp0, *rp1;
   double                 *rcp;
                       
   hypre_Index             loop_size;
   hypre_IndexRef          start;
   hypre_Index             startc;
   hypre_Index             stridec;
                       
   hypre_StructStencil    *stencil;
   hypre_Index            *stencil_shape;

   int                     compute_i, fi, ci, j;
   int                     loopi, loopj, loopk;

   /*-----------------------------------------------------------------------
    * Initialize some things.
    *-----------------------------------------------------------------------*/

   hypre_BeginTiming(restrict_data -> time_index);

   R_stored_as_transpose = (restrict_data -> R_stored_as_transpose);
   compute_pkg   = (restrict_data -> compute_pkg);
   cindex        = (restrict_data -> cindex);
   stride        = (restrict_data -> stride);

   stencil       = hypre_StructMatrixStencil(R);
   stencil_shape = hypre_StructStencilShape(stencil);

   hypre_SetIndex(stridec, 1, 1, 1);

   /*--------------------------------------------------------------------
    * Restrict the residual.
    *--------------------------------------------------------------------*/

   fgrid = hypre_StructVectorGrid(r);
   fgrid_ids = hypre_StructGridIDs(fgrid);
   cgrid = hypre_StructVectorGrid(rc);
   cgrid_boxes = hypre_StructGridBoxes(cgrid);
   cgrid_ids = hypre_StructGridIDs(cgrid);

   for (compute_i = 0; compute_i < 2; compute_i++)
   {
      switch(compute_i)
      {
         case 0:
         {
            rp = hypre_StructVectorData(r);
            hypre_InitializeIndtComputations(compute_pkg, rp, &comm_handle);
            compute_box_aa = hypre_ComputePkgIndtBoxes(compute_pkg);
         }
         break;

         case 1:
         {
            hypre_FinalizeIndtComputations(comm_handle);
            compute_box_aa = hypre_ComputePkgDeptBoxes(compute_pkg);
         }
         break;
      }

      fi = 0;
      hypre_ForBoxArrayI(ci, cgrid_boxes)
         {
            while (fgrid_ids[fi] != cgrid_ids[ci])
            {
               fi++;
            }

            compute_box_a = hypre_BoxArrayArrayBoxArray(compute_box_aa, fi);

            R_dbox  = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(R),  fi);
            r_dbox  = hypre_BoxArrayBox(hypre_StructVectorDataSpace(r),  fi);
            rc_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(rc), ci);

            if (R_stored_as_transpose)
            {
               Rp0 = hypre_StructMatrixBoxData(R, fi, 1) -
                  hypre_BoxOffsetDistance(R_dbox, stencil_shape[1]);
               Rp1 = hypre_StructMatrixBoxData(R, fi, 0);
            }
            else
            {
               Rp0 = hypre_StructMatrixBoxData(R, fi, 0);
               Rp1 = hypre_StructMatrixBoxData(R, fi, 1);
            }
            rp  = hypre_StructVectorBoxData(r, fi);
            rp0 = rp + hypre_BoxOffsetDistance(r_dbox, stencil_shape[0]);
            rp1 = rp + hypre_BoxOffsetDistance(r_dbox, stencil_shape[1]);
            rcp = hypre_StructVectorBoxData(rc, ci);

            hypre_ForBoxI(j, compute_box_a)
               {
                  compute_box = hypre_BoxArrayBox(compute_box_a, j);

                  start  = hypre_BoxIMin(compute_box);
                  hypre_StructMapFineToCoarse(start, cindex, stride, startc);

                  hypre_BoxGetStrideSize(compute_box, stride, loop_size);
                  hypre_BoxLoop3Begin(loop_size,
                                      R_dbox,  startc, stridec, Ri,
                                      r_dbox,  start,  stride,  ri,
                                      rc_dbox, startc, stridec, rci);
#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,Ri,ri,rci
#include "hypre_box_smp_forloop.h"
                  hypre_BoxLoop3For(loopi, loopj, loopk, Ri, ri, rci)
                     {
                        rcp[rci] = rp[ri] + (Rp0[Ri] * rp0[ri] +
                                             Rp1[Ri] * rp1[ri]);
                     }
                  hypre_BoxLoop3End(Ri, ri, rci);
               }
         }
Exemple #14
0
HYPRE_Int
hypre_SparseMSGInterp( void               *interp_vdata,
                       hypre_StructMatrix *P,
                       hypre_StructVector *xc,
                       hypre_StructVector *e            )
{
   HYPRE_Int ierr = 0;

   hypre_SparseMSGInterpData   *interp_data = interp_vdata;

   hypre_ComputePkg       *compute_pkg;
   hypre_IndexRef          cindex;
   hypre_IndexRef          findex;
   hypre_IndexRef          stride;
   hypre_IndexRef          strideP;

   hypre_StructGrid       *fgrid;
   HYPRE_Int              *fgrid_ids;
   hypre_StructGrid       *cgrid;
   hypre_BoxArray         *cgrid_boxes;
   HYPRE_Int              *cgrid_ids;

   hypre_CommHandle       *comm_handle;
                       
   hypre_BoxArrayArray    *compute_box_aa;
   hypre_BoxArray         *compute_box_a;
   hypre_Box              *compute_box;
                       
   hypre_Box              *P_dbox;
   hypre_Box              *xc_dbox;
   hypre_Box              *e_dbox;
                       
   HYPRE_Int               Pi;
   HYPRE_Int               xci;
   HYPRE_Int               ei;
                         
   double                 *Pp0, *Pp1;
   double                 *xcp;
   double                 *ep, *ep0, *ep1;
                       
   hypre_Index             loop_size;
   hypre_Index             start;
   hypre_Index             startc;
   hypre_Index             startP;
   hypre_Index             stridec;
                       
   hypre_StructStencil    *stencil;
   hypre_Index            *stencil_shape;

   HYPRE_Int               compute_i, fi, ci, j;

   /*-----------------------------------------------------------------------
    * Initialize some things
    *-----------------------------------------------------------------------*/

   hypre_BeginTiming(interp_data -> time_index);

   compute_pkg   = (interp_data -> compute_pkg);
   cindex        = (interp_data -> cindex);
   findex        = (interp_data -> findex);
   stride        = (interp_data -> stride);
   strideP       = (interp_data -> strideP);

   stencil       = hypre_StructMatrixStencil(P);
   stencil_shape = hypre_StructStencilShape(stencil);

   hypre_SetIndex(stridec, 1, 1, 1);

   /*-----------------------------------------------------------------------
    * Compute e at coarse points (injection)
    *-----------------------------------------------------------------------*/

   fgrid = hypre_StructVectorGrid(e);
   fgrid_ids = hypre_StructGridIDs(fgrid);
   cgrid = hypre_StructVectorGrid(xc);
   cgrid_boxes = hypre_StructGridBoxes(cgrid);
   cgrid_ids = hypre_StructGridIDs(cgrid);

   fi = 0;
   hypre_ForBoxI(ci, cgrid_boxes)
   {
      while (fgrid_ids[fi] != cgrid_ids[ci])
      {
         fi++;
      }

      compute_box = hypre_BoxArrayBox(cgrid_boxes, ci);

      hypre_CopyIndex(hypre_BoxIMin(compute_box), startc);
      hypre_StructMapCoarseToFine(startc, cindex, stride, start);

      e_dbox  = hypre_BoxArrayBox(hypre_StructVectorDataSpace(e), fi);
      xc_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(xc), ci);

      ep  = hypre_StructVectorBoxData(e, fi);
      xcp = hypre_StructVectorBoxData(xc, ci);

      hypre_BoxGetSize(compute_box, loop_size);

      hypre_BoxLoop2Begin(hypre_StructMatrixDim(P), loop_size,
                          e_dbox,  start,  stride,  ei,
                          xc_dbox, startc, stridec, xci);
#ifdef HYPRE_USING_OPENMP
#pragma omp parallel for private(HYPRE_BOX_PRIVATE,ei,xci) HYPRE_SMP_SCHEDULE
#endif
      hypre_BoxLoop2For(ei, xci)
      {
         ep[ei] = xcp[xci];
      }
      hypre_BoxLoop2End(ei, xci);
   }

   /*-----------------------------------------------------------------------
    * Compute e at fine points
    *-----------------------------------------------------------------------*/

   for (compute_i = 0; compute_i < 2; compute_i++)
   {
      switch(compute_i)
      {
         case 0:
         {
            ep = hypre_StructVectorData(e);
            hypre_InitializeIndtComputations(compute_pkg, ep, &comm_handle);
            compute_box_aa = hypre_ComputePkgIndtBoxes(compute_pkg);
         }
         break;

         case 1:
         {
            hypre_FinalizeIndtComputations(comm_handle);
            compute_box_aa = hypre_ComputePkgDeptBoxes(compute_pkg);
         }
         break;
      }

      hypre_ForBoxArrayI(fi, compute_box_aa)
      {
         compute_box_a = hypre_BoxArrayArrayBoxArray(compute_box_aa, fi);

         P_dbox = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(P), fi);
         e_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(e), fi);

         Pp0 = hypre_StructMatrixBoxData(P, fi, 0);
         Pp1 = hypre_StructMatrixBoxData(P, fi, 1);
         ep  = hypre_StructVectorBoxData(e, fi);
         ep0 = ep + hypre_BoxOffsetDistance(e_dbox, stencil_shape[0]);
         ep1 = ep + hypre_BoxOffsetDistance(e_dbox, stencil_shape[1]);

         hypre_ForBoxI(j, compute_box_a)
         {
            compute_box = hypre_BoxArrayBox(compute_box_a, j);

            hypre_CopyIndex(hypre_BoxIMin(compute_box), start);
            hypre_StructMapFineToCoarse(start,  findex, stride,  startc);
            hypre_StructMapCoarseToFine(startc, cindex, strideP, startP);

            hypre_BoxGetStrideSize(compute_box, stride, loop_size);

            hypre_BoxLoop2Begin(hypre_StructMatrixDim(P), loop_size,
                                P_dbox, startP, strideP, Pi,
                                e_dbox, start,  stride,  ei);
#ifdef HYPRE_USING_OPENMP
#pragma omp parallel for private(HYPRE_BOX_PRIVATE,Pi,ei) HYPRE_SMP_SCHEDULE
#endif
            hypre_BoxLoop2For(Pi, ei)
            {
               ep[ei] =  (Pp0[Pi] * ep0[ei] +
                          Pp1[Pi] * ep1[ei]);
            }
            hypre_BoxLoop2End(Pi, ei);
         }
      }
Exemple #15
0
int
hypre_StructMatvecCompute( void               *matvec_vdata,
                           double              alpha,
                           hypre_StructMatrix *A,
                           hypre_StructVector *x,
                           double              beta,
                           hypre_StructVector *y            )
{
   int ierr = 0;

   hypre_StructMatvecData  *matvec_data = matvec_vdata;
                          
   hypre_ComputePkg        *compute_pkg;
                          
   hypre_CommHandle        *comm_handle;
                          
   hypre_BoxArrayArray     *compute_box_aa;
   hypre_BoxArray          *compute_box_a;
   hypre_Box               *compute_box;
                          
   hypre_Box               *A_data_box;
   hypre_Box               *x_data_box;
   hypre_Box               *y_data_box;
                          
   int                      Ai;
   int                      xi;
   int                      xoff0;
   int                      xoff1;
   int                      xoff2;
   int                      xoff3;
   int                      xoff4;
   int                      xoff5;
   int                      xoff6;
   int                      yi;
                          
   double                  *Ap0;
   double                  *Ap1;
   double                  *Ap2;
   double                  *Ap3;
   double                  *Ap4;
   double                  *Ap5;
   double                  *Ap6;
   double                  *xp;
   double                  *yp;
                          
   hypre_BoxArray          *boxes;
   hypre_Box               *box;
   hypre_Index              loop_size;
   hypre_IndexRef           start;
   hypre_IndexRef           stride;
                          
   hypre_StructStencil     *stencil;
   hypre_Index             *stencil_shape;
   int                      stencil_size;
   int                      depth;
                          
   double                   temp;
   int                      compute_i, i, j, si;
   int                      loopi, loopj, loopk;

   /*-----------------------------------------------------------------------
    * Initialize some things
    *-----------------------------------------------------------------------*/

   compute_pkg = (matvec_data -> compute_pkg);

   stride = hypre_ComputePkgStride(compute_pkg);

   /*-----------------------------------------------------------------------
    * Do (alpha == 0.0) computation
    *-----------------------------------------------------------------------*/

   if (alpha == 0.0)
   {
      boxes = hypre_StructGridBoxes(hypre_StructMatrixGrid(A));
      hypre_ForBoxI(i, boxes)
         {
            box   = hypre_BoxArrayBox(boxes, i);
            start = hypre_BoxIMin(box);

            y_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(y), i);
            yp = hypre_StructVectorBoxData(y, i);

            hypre_BoxGetSize(box, loop_size);

            hypre_BoxLoop1Begin(loop_size,
                                y_data_box, start, stride, yi);
#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,yi
#include "hypre_box_smp_forloop.h"
            hypre_BoxLoop1For(loopi, loopj, loopk, yi)
               {
                  yp[yi] *= beta;
               }
            hypre_BoxLoop1End(yi);
         }
Exemple #16
0
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);
   
      }
/*--------------------------------------------------------------------------
 * 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 */
double
hypre_StructOverlapInnerProd( hypre_StructVector *x,
                              hypre_StructVector *y )
{
   double               final_innerprod_result;
   double               local_result, overlap_result;
   double               process_result;
                   
   hypre_Box           *x_data_box;
   hypre_Box           *y_data_box;

   hypre_BoxArray      *overlap_boxes;
                   
   HYPRE_Int            xi;
   HYPRE_Int            yi;
                   
   double              *xp;
   double              *yp;
                   
   hypre_BoxArray      *boxes;
   hypre_Box           *boxi, *boxj, intersect_box;

   hypre_StructGrid    *grid= hypre_StructVectorGrid(y);
   hypre_BoxManager    *boxman = hypre_StructGridBoxMan(grid);
   hypre_BoxArray      *neighbor_boxes;
   HYPRE_Int           *neighbors_procs= NULL;
   hypre_BoxArray      *selected_nboxes;
   hypre_BoxArray      *tmp_box_array, *tmp2_box_array;

   hypre_Index          loop_size;
   hypre_IndexRef       start;
   hypre_Index          unit_stride;
                   
   HYPRE_Int            i, j;
   HYPRE_Int            myid;
   HYPRE_Int            boxarray_size;
   HYPRE_Int            loopi, loopj, loopk;
#ifdef HYPRE_USE_PTHREADS
   HYPRE_Int            threadid = hypre_GetThreadID();
#endif

   
   local_result = 0.0;
   process_result = 0.0;
   hypre_SetIndex(unit_stride, 1, 1, 1);

   hypre_MPI_Comm_rank(hypre_StructVectorComm(y), &myid);

   /*-----------------------------------------------------------------------
    * Determine the overlapped boxes on this local processor.
    *-----------------------------------------------------------------------*/
   boxes        = hypre_StructGridBoxes(hypre_StructVectorGrid(y));
   boxarray_size= hypre_BoxArraySize(boxes);

   /*-----------------------------------------------------------------------
    * To compute the inner product over this local processor, given a box, 
    * the inner product between x & y is computed over the whole box and
    * over any overlapping between this box and overlap_boxes. The latter
    * result is subtracted from the former. Overlapping between more than
    * two boxes are handled.
    *-----------------------------------------------------------------------*/
   hypre_ForBoxI(i, boxes)
   {
      boxi  = hypre_BoxArrayBox(boxes, i);
      start = hypre_BoxIMin(boxi);

      x_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(x), i);
      y_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(y), i);

      xp = hypre_StructVectorBoxData(x, i);
      yp = hypre_StructVectorBoxData(y, i);

      hypre_BoxGetSize(boxi, loop_size);

#ifdef HYPRE_USE_PTHREADS
   local_result_ref[threadid] = &local_result;
#endif

      hypre_BoxLoop2Begin(loop_size,
                          x_data_box, start, unit_stride, xi,
                          y_data_box, start, unit_stride, yi);
#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,xi,yi
#define HYPRE_SMP_REDUCTION_OP +
#define HYPRE_SMP_REDUCTION_VARS local_result
#include "hypre_box_smp_forloop.h"
      hypre_BoxLoop2For(loopi, loopj, loopk, xi, yi)
      {
          local_result += xp[xi] * yp[yi];
      }
int
hypre_SMGResidualSetup( void               *residual_vdata,
                        hypre_StructMatrix *A,
                        hypre_StructVector *x,
                        hypre_StructVector *b,
                        hypre_StructVector *r              )
{
   int ierr = 0;

   hypre_SMGResidualData *residual_data = (hypre_SMGResidualData *)residual_vdata;

   hypre_IndexRef          base_index  = (residual_data -> base_index);
   hypre_IndexRef          base_stride = (residual_data -> base_stride);
   hypre_Index             unit_stride;

   hypre_StructGrid       *grid;
   hypre_StructStencil    *stencil;
                       
   hypre_BoxArrayArray    *send_boxes;
   hypre_BoxArrayArray    *recv_boxes;
   int                   **send_processes;
   int                   **recv_processes;
   hypre_BoxArrayArray    *indt_boxes;
   hypre_BoxArrayArray    *dept_boxes;
                       
   hypre_BoxArray         *base_points;
   hypre_ComputePkg       *compute_pkg;

   /*----------------------------------------------------------
    * Set up base points and the compute package
    *----------------------------------------------------------*/

   grid    = hypre_StructMatrixGrid(A);
   stencil = hypre_StructMatrixStencil(A);

   hypre_SetIndex(unit_stride, 1, 1, 1);

   base_points = hypre_BoxArrayDuplicate(hypre_StructGridBoxes(grid));
   hypre_ProjectBoxArray(base_points, base_index, base_stride);

   hypre_CreateComputeInfo(grid, stencil,
                        &send_boxes, &recv_boxes,
                        &send_processes, &recv_processes,
                        &indt_boxes, &dept_boxes);

   hypre_ProjectBoxArrayArray(indt_boxes, base_index, base_stride);
   hypre_ProjectBoxArrayArray(dept_boxes, base_index, base_stride);

   hypre_ComputePkgCreate(send_boxes, recv_boxes,
                       unit_stride, unit_stride,
                       send_processes, recv_processes,
                       indt_boxes, dept_boxes,
                       base_stride, grid,
                       hypre_StructVectorDataSpace(x), 1,
                       &compute_pkg);

   /*----------------------------------------------------------
    * Set up the residual data structure
    *----------------------------------------------------------*/

   (residual_data -> A)           = hypre_StructMatrixRef(A);
   (residual_data -> x)           = hypre_StructVectorRef(x);
   (residual_data -> b)           = hypre_StructVectorRef(b);
   (residual_data -> r)           = hypre_StructVectorRef(r);
   (residual_data -> base_points) = base_points;
   (residual_data -> compute_pkg) = compute_pkg;

   /*-----------------------------------------------------
    * Compute flops
    *-----------------------------------------------------*/

   (residual_data -> flops) =
      (hypre_StructMatrixGlobalSize(A) + hypre_StructVectorGlobalSize(x)) /
      (hypre_IndexX(base_stride) *
       hypre_IndexY(base_stride) *
       hypre_IndexZ(base_stride)  );

   return ierr;
}
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];
            }
         }
Exemple #21
0
HYPRE_Int
hypre_FacSemiRestrictSetup2( void                 *fac_restrict_vdata,
                             hypre_SStructVector  *r,
                             HYPRE_Int             part_crse,
                             HYPRE_Int             part_fine,
                             hypre_SStructPVector *rc,
                             hypre_Index           rfactors )
{
   HYPRE_Int                 ierr = 0;

   hypre_FacSemiRestrictData2 *fac_restrict_data = fac_restrict_vdata;
   MPI_Comm                    comm= hypre_SStructPVectorComm(rc);
   hypre_CommInfo             *comm_info;
   hypre_CommPkg             **interlevel_comm;

   hypre_SStructPVector       *rf= hypre_SStructVectorPVector(r, part_fine);
   hypre_StructVector         *s_rc, *s_cvector;
   hypre_SStructPGrid         *pgrid;

   hypre_SStructPVector       *fgrid_cvectors;
   hypre_SStructPGrid         *fgrid_coarsen;
   hypre_BoxArrayArray       **identity_arrayboxes;
   hypre_BoxArrayArray       **fullwgt_ownboxes;
   hypre_BoxArrayArray       **fullwgt_sendboxes;
   hypre_BoxArray             *boxarray;
   hypre_BoxArray             *tmp_boxarray, *intersect_boxes;
   HYPRE_Int                ***own_cboxnums;

   hypre_BoxArrayArray       **send_boxes, *send_rboxes;
   HYPRE_Int                ***send_processes;
   HYPRE_Int                ***send_remote_boxnums;

   hypre_BoxArrayArray       **recv_boxes, *recv_rboxes;
   HYPRE_Int                ***recv_processes;
   HYPRE_Int                ***recv_remote_boxnums;

   hypre_BoxManager           *boxman;
   hypre_BoxManEntry         **boxman_entries;
   HYPRE_Int                   nboxman_entries;

   hypre_Box                   box, scaled_box;

   hypre_Index                 zero_index, index, ilower, iupper;
   HYPRE_Int                   ndim= hypre_SStructVectorNDim(r);
   HYPRE_Int                   myproc, proc;
   HYPRE_Int                   nvars, vars;
   HYPRE_Int                   num_values;

   HYPRE_Int                   i, cnt1, cnt2;
   HYPRE_Int                   fi, ci;

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

   nvars= hypre_SStructPVectorNVars(rc);
  (fac_restrict_data -> nvars)=  nvars;
   hypre_CopyIndex(rfactors, (fac_restrict_data -> stride));
   for (i= ndim; i< 3; i++)
   {
      rfactors[i]= 1;
   }

   /* work vector for storing the fullweighted fgrid boxes */
   hypre_SStructPGridCreate(hypre_SStructPVectorComm(rf), ndim, &fgrid_coarsen);
   pgrid= hypre_SStructPVectorPGrid(rf);
   for (vars= 0; vars< nvars; vars++)
   {
      boxarray= hypre_StructGridBoxes(hypre_SStructPGridSGrid(pgrid, vars));
      hypre_ForBoxI(fi, boxarray)
      { 
         hypre_CopyBox(hypre_BoxArrayBox(boxarray, fi), &box);
         hypre_StructMapFineToCoarse(hypre_BoxIMin(&box), zero_index,
                                     rfactors, hypre_BoxIMin(&box));
         hypre_StructMapFineToCoarse(hypre_BoxIMax(&box), zero_index,
                                     rfactors, hypre_BoxIMax(&box));
         hypre_SStructPGridSetExtents(fgrid_coarsen,
                                      hypre_BoxIMin(&box),
                                      hypre_BoxIMax(&box));
      }
   }
Exemple #22
0
HYPRE_Int 
hypre_Maxwell_PhysBdy( hypre_SStructGrid      **grid_l,
                       HYPRE_Int                num_levels,
                       hypre_Index              rfactors,
                       HYPRE_Int             ***BdryRanksl_ptr, 
                       HYPRE_Int              **BdryRanksCntsl_ptr )
{

   MPI_Comm                comm= (grid_l[0]-> comm);

   HYPRE_Int             **BdryRanks_l;
   HYPRE_Int              *BdryRanksCnts_l;

   HYPRE_Int              *npts;
   HYPRE_Int              *ranks, *upper_rank, *lower_rank;
   hypre_BoxManEntry      *boxman_entry;

   hypre_SStructGrid      *grid;
   hypre_SStructPGrid     *pgrid;
   hypre_StructGrid       *cell_fgrid, *cell_cgrid, *sgrid;

   hypre_BoxArrayArray ****bdry;
   hypre_BoxArrayArray    *fbdry;
   hypre_BoxArrayArray    *cbdry;

   hypre_BoxArray         *box_array;
   hypre_BoxArray         *fboxes, *cboxes;

   hypre_Box              *fbox, *cbox;
   hypre_Box              *box, *contract_fbox, rbox;
   hypre_Box               intersect;

   HYPRE_Int             **cbox_mapping, **fbox_mapping;
   HYPRE_Int             **boxes_with_bdry;

   HYPRE_Int               ndim, nvars;
   HYPRE_Int               nboxes, nfboxes;
   HYPRE_Int               boxi;
   
   hypre_Index             zero_shift, upper_shift, lower_shift;
   hypre_Index             loop_size, start, index, lindex;

   HYPRE_Int               i, j, k, l, m, n, p;
   HYPRE_Int               d;
   HYPRE_Int               cnt;

   HYPRE_Int               part= 0;  /* NOTE, ASSUMING ONE PART */
   HYPRE_Int               matrix_type= HYPRE_PARCSR;
   HYPRE_Int               myproc;

   HYPRE_Int               ierr= 0;

   hypre_MPI_Comm_rank(comm, &myproc);

   ndim= hypre_SStructGridNDim(grid_l[0]);
   hypre_SetIndex3(zero_shift, 0, 0, 0);

   hypre_BoxInit(&intersect, ndim);

   /* bounding global ranks of this processor & allocate boundary box markers. */
   upper_rank= hypre_CTAlloc(HYPRE_Int, num_levels);
   lower_rank= hypre_CTAlloc(HYPRE_Int, num_levels);

   boxes_with_bdry= hypre_TAlloc(HYPRE_Int *, num_levels);
   for (i= 0; i< num_levels; i++)
   {
      grid = grid_l[i];
      lower_rank[i]= hypre_SStructGridStartRank(grid);

      /* note we are assuming only one part */
      pgrid= hypre_SStructGridPGrid(grid, part);
      nvars= hypre_SStructPGridNVars(pgrid);
      sgrid= hypre_SStructPGridSGrid(pgrid, nvars-1);
      box_array= hypre_StructGridBoxes(sgrid);
      box  = hypre_BoxArrayBox(box_array, hypre_BoxArraySize(box_array)-1);

      hypre_SStructGridBoxProcFindBoxManEntry(grid, part, nvars-1,
                                              hypre_BoxArraySize(box_array)-1, myproc, &boxman_entry);
      hypre_SStructBoxManEntryGetGlobalCSRank(boxman_entry, hypre_BoxIMax(box), 
                                              &upper_rank[i]);

      sgrid= hypre_SStructPGridCellSGrid(pgrid);
      box_array= hypre_StructGridBoxes(sgrid);
      boxes_with_bdry[i]= hypre_CTAlloc(HYPRE_Int, hypre_BoxArraySize(box_array));
   }
 
   /*-----------------------------------------------------------------------------
    * construct box_number mapping between levels, and offset strides because of 
    * projection coarsening. Note: from the way the coarse boxes are created and
    * numbered, to determine the coarse box that matches the fbox, we need to
    * only check the tail end of the list of cboxes. In fact, given fbox_i,
    * if it's coarsened extents do not interesect with the first coarse box of the
    * tail end, then this fbox vanishes in the coarsening.
    *   c/fbox_mapping gives the fine/coarse box mapping between two consecutive levels
    *   of the multilevel hierarchy. 
    *-----------------------------------------------------------------------------*/
   if (num_levels > 1)
   {
      cbox_mapping= hypre_CTAlloc(HYPRE_Int *, num_levels);
      fbox_mapping= hypre_CTAlloc(HYPRE_Int *, num_levels);
   }