/*--------------------------------------------------------------------------
 * 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 */
Example #2
0
/*--------------------------------------------------------------------------
 * hypre_CFInterfaceExtents: Given a cgrid_box, a fgrid_box, and stencils,
 * find the extents of the C/F interface (interface nodes in the C box).
 * Boxes corresponding to stencil shifts are stored in the first stencil_size
 * boxes, and the union of these are appended to the end of the returned
 * box_array.
 *--------------------------------------------------------------------------*/
hypre_BoxArray *
hypre_CFInterfaceExtents( hypre_Box              *fgrid_box,
                          hypre_Box              *cgrid_box,
                          hypre_StructStencil    *stencils,
                          hypre_Index             rfactors )
{

   hypre_BoxArray        *stencil_box_extents;
   hypre_BoxArray        *union_boxes;
   hypre_Box             *cfine_box;
   hypre_Box             *box;

   hypre_Index            stencil_shape, cstart, zero_index, neg_index;
   HYPRE_Int              stencil_size;
   HYPRE_Int              abs_stencil;

   HYPRE_Int              ndim= hypre_StructStencilDim(stencils);
   HYPRE_Int              i, j;
    
   hypre_ClearIndex(zero_index);
   hypre_ClearIndex(neg_index);
   for (i= 0; i< ndim; i++)
   {
      neg_index[i]= -1;
   }
   hypre_CopyIndex(hypre_BoxIMin(cgrid_box), cstart);

   stencil_size       = hypre_StructStencilSize(stencils);
   stencil_box_extents= hypre_BoxArrayCreate(stencil_size);
   union_boxes        = hypre_BoxArrayCreate(0);

   for (i= 0; i< stencil_size; i++)
   {
       hypre_CopyIndex(hypre_StructStencilElement(stencils, i), stencil_shape);
       AbsStencilShape(stencil_shape, abs_stencil);

       if (abs_stencil)  /* only do if not the centre stencil */
       {
          cfine_box= hypre_CF_StenBox(fgrid_box, cgrid_box, stencil_shape, rfactors,
                                      ndim);

          if ( hypre_BoxVolume(cfine_box) )
          {
             hypre_AppendBox(cfine_box, union_boxes);
             hypre_CopyBox(cfine_box, hypre_BoxArrayBox(stencil_box_extents, i));
             for (j= 0; j< ndim; j++)
             {
                hypre_BoxIMin(cfine_box)[j]-=  cstart[j];
                hypre_BoxIMax(cfine_box)[j]-=  cstart[j];
             }
             hypre_CopyBox(cfine_box, hypre_BoxArrayBox(stencil_box_extents, i));
          }
         
          else
          {
             hypre_BoxSetExtents(hypre_BoxArrayBox(stencil_box_extents, i),
                                 zero_index, neg_index);
          }

          hypre_BoxDestroy(cfine_box);
       }

       else /* centre */
       {
           hypre_BoxSetExtents(hypre_BoxArrayBox(stencil_box_extents, i),
                               zero_index, neg_index);
       }
   }

   /*--------------------------------------------------------------------------
    * Union the stencil_box_extents to get the full CF extents and append to
    * the end of the stencil_box_extents BoxArray. Then shift the unioned boxes
    * by cstart.
    *--------------------------------------------------------------------------*/
   if (hypre_BoxArraySize(union_boxes) > 1)
   {
       hypre_UnionBoxes(union_boxes);
   }

   hypre_ForBoxI(i, union_boxes)
   {
       hypre_AppendBox(hypre_BoxArrayBox(union_boxes, i), stencil_box_extents);
   }