Exemplo n.º 1
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);
   
      }
Exemplo n.º 2
0
HYPRE_Int
hypre_PFMGSetup( void               *pfmg_vdata,
                 hypre_StructMatrix *A,
                 hypre_StructVector *b,
                 hypre_StructVector *x        )
{
   hypre_PFMGData       *pfmg_data = pfmg_vdata;

   MPI_Comm              comm = (pfmg_data -> comm);
                     
   HYPRE_Int             relax_type =       (pfmg_data -> relax_type);
   HYPRE_Int             usr_jacobi_weight= (pfmg_data -> usr_jacobi_weight);
   double                jacobi_weight    = (pfmg_data -> jacobi_weight);
   HYPRE_Int             skip_relax =       (pfmg_data -> skip_relax);
   double               *dxyz       =       (pfmg_data -> dxyz);
   HYPRE_Int             rap_type;
                     
   HYPRE_Int             max_iter;
   HYPRE_Int             max_levels;
                      
   HYPRE_Int             num_levels;
                     
   hypre_Index           cindex;
   hypre_Index           findex;
   hypre_Index           stride;

   hypre_Index           coarsen;

   HYPRE_Int            *cdir_l;
   HYPRE_Int            *active_l;
   hypre_StructGrid    **grid_l;
   hypre_StructGrid    **P_grid_l;
                    
   double               *data;
   HYPRE_Int             data_size = 0;
   double               *relax_weights;
   double               *mean, *deviation;
   double                alpha, beta;

   hypre_StructMatrix  **A_l;
   hypre_StructMatrix  **P_l;
   hypre_StructMatrix  **RT_l;
   hypre_StructVector  **b_l;
   hypre_StructVector  **x_l;

   /* temp vectors */
   hypre_StructVector  **tx_l;
   hypre_StructVector  **r_l;
   hypre_StructVector  **e_l;

   void                **relax_data_l;
   void                **matvec_data_l;
   void                **restrict_data_l;
   void                **interp_data_l;

   hypre_StructGrid     *grid;
   HYPRE_Int             dim;

   hypre_Box            *cbox;

   double                min_dxyz;
   HYPRE_Int             cdir, periodic, cmaxsize;
   HYPRE_Int             d, l;
   HYPRE_Int             dxyz_flag;
                       
   HYPRE_Int             b_num_ghost[]  = {0, 0, 0, 0, 0, 0};
   HYPRE_Int             x_num_ghost[]  = {1, 1, 1, 1, 1, 1};

   HYPRE_Int             ierr = 0;
#if DEBUG
   char                  filename[255];
#endif


   /*-----------------------------------------------------
    * Set up coarse grids
    *-----------------------------------------------------*/

   grid  = hypre_StructMatrixGrid(A);
   dim   = hypre_StructGridDim(grid);

   /* Compute a new max_levels value based on the grid */
   cbox = hypre_BoxDuplicate(hypre_StructGridBoundingBox(grid));
   max_levels =
      hypre_Log2(hypre_BoxSizeD(cbox, 0)) + 2 +
      hypre_Log2(hypre_BoxSizeD(cbox, 1)) + 2 +
      hypre_Log2(hypre_BoxSizeD(cbox, 2)) + 2;
   if ((pfmg_data -> max_levels) > 0)
   {
      max_levels = hypre_min(max_levels, (pfmg_data -> max_levels));
   }
   (pfmg_data -> max_levels) = max_levels;

   /* compute dxyz */
   if ((dxyz[0] == 0) || (dxyz[1] == 0) || (dxyz[2] == 0))
   {
      mean = hypre_CTAlloc(double, 3);
      deviation = hypre_CTAlloc(double, 3);
      hypre_PFMGComputeDxyz(A, dxyz, mean, deviation);
        
      dxyz_flag= 0;
      for (d = 0; d < dim; d++)
      {
         deviation[d] -= mean[d]*mean[d];
         /* square of coeff. of variation */
         if (deviation[d]/(mean[d]*mean[d]) > .1)
         {
            dxyz_flag= 1;
            break;
         }
      }
      hypre_TFree(mean);
      hypre_TFree(deviation);
   }
Exemplo n.º 3
0
/*--------------------------------------------------------------------------
 * hypre_CF_StenBox: Given a cgrid_box, a fgrid_box, and a stencil_shape,
 * the stencil_shape direction. Returns an empty box if these two boxes
 * are not connected in the stencil_shape direction.
 *--------------------------------------------------------------------------*/
hypre_Box *
hypre_CF_StenBox( hypre_Box              *fgrid_box,
                  hypre_Box              *cgrid_box,
                  hypre_Index             stencil_shape,
                  hypre_Index             rfactors,
                  HYPRE_Int               ndim )
{
   hypre_Box              coarsen_box;
   hypre_Box              contracted_box;
   hypre_Box              extended_box;
   hypre_Box              intersect_box;
   hypre_Box             *stenbox;

   hypre_Box              shift_cbox, shift_ibox;
   hypre_Index            size_cbox, size_ibox;

   hypre_Index            temp_index;
   hypre_Index            shift_index;

   HYPRE_Int              i, remainder, intersect_size;

   hypre_ClearIndex(temp_index);
   stenbox = hypre_BoxCreate();

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

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

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

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

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

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

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

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

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

   return stenbox;
}