Пример #1
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;
}
Пример #2
0
int
hypre_SStructUMatrixSetBoxValues( hypre_SStructMatrix *matrix,
                                  int                  part,
                                  hypre_Index          ilower,
                                  hypre_Index          iupper,
                                  int                  var,
                                  int                  nentries,
                                  int                 *entries,
                                  double              *values,
                                  int                  add_to )
{
    HYPRE_IJMatrix        ijmatrix = hypre_SStructMatrixIJMatrix(matrix);
    hypre_SStructGraph   *graph   = hypre_SStructMatrixGraph(matrix);
    hypre_SStructGrid    *grid    = hypre_SStructGraphGrid(graph);
    hypre_SStructStencil *stencil = hypre_SStructGraphStencil(graph, part, var);
    int                  *vars    = hypre_SStructStencilVars(stencil);
    hypre_Index          *shape   = hypre_SStructStencilShape(stencil);
    int                   size    = hypre_SStructStencilSize(stencil);
    hypre_IndexRef        offset;
    hypre_BoxMap         *map;
    hypre_BoxMapEntry   **map_entries;
    int                   nmap_entries;
    hypre_BoxMapEntry   **map_to_entries;
    int                   nmap_to_entries;
    int                   nrows;
    int                  *ncols;
    HYPRE_BigInt         *rows;
    HYPRE_BigInt         *cols;
    double               *ijvalues;
    hypre_Box            *box;
    hypre_Box            *to_box;
    hypre_Box            *map_box;
    hypre_Box            *int_box;
    hypre_Index           index;
    hypre_Index           rs, cs;
    int                   sy, sz;
    HYPRE_BigInt          row_base, col_base;
    int                   val_base;
    int                   e, entry, ii, jj, i, j, k;
    int                   proc, myproc;
    /* GEC1002 the matrix type */
    int                   matrix_type = hypre_SStructMatrixObjectType(matrix);

    box = hypre_BoxCreate();

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

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

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

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

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

        for (ii = 0; ii < nmap_entries; ii++)
        {
            /* Only Set values if I am the owner process; off-process AddTo and Get
             * values are done by IJ */
            if (!add_to)
            {
                hypre_SStructMapEntryGetProcess(map_entries[ii], &proc);
                MPI_Comm_rank(hypre_SStructGridComm(grid), &myproc);
                if (proc != myproc)
                {
                    continue;
                }
            }

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

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

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

                hypre_CopyBox(box, to_box);

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

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

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

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

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

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

                    hypre_CopyIndex(hypre_BoxIMin(int_box), index);

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

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

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

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

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

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

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

                hypre_TFree(map_to_entries);
            }

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

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

        hypre_TFree(map_entries);

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

        hypre_BoxDestroy(to_box);
        hypre_BoxDestroy(map_box);
        hypre_BoxDestroy(int_box);
    }
Пример #3
0
int
hypre_StructCoarsen( hypre_StructGrid  *fgrid,
                     hypre_Index        index,
                     hypre_Index        stride,
                     int                prune,
                     hypre_StructGrid **cgrid_ptr )
{
   int ierr = 0;

   hypre_StructGrid   *cgrid;
                      
   MPI_Comm            comm;
   int                 dim;
   hypre_BoxNeighbors *neighbors;
   hypre_BoxArray     *hood_boxes;
   int                 num_hood;
   int                *hood_procs;
   int                *hood_ids;
   int                 first_local;
   int                 num_local;
   int                 num_periodic;
   int                 max_distance;
   hypre_Box          *bounding_box;
   hypre_Index         periodic;

   MPI_Request        *send_requests;
   MPI_Status         *send_status;
   int                *send_buffer;
   int                 send_size;
   MPI_Request        *recv_requests;
   MPI_Status         *recv_status;
   int               **recv_buffers;
   int                *recv_sizes;
   int                 my_rank;

   int                *send_procs;
   int                *recv_procs;
   int                 num_sends;
   int                 num_recvs;
                      
   hypre_BoxArray     *new_hood_boxes;
   int                 new_num_hood;
   int                *new_hood_procs;
   int                *new_hood_ids;
   int                 new_first_local;
   int                 new_num_local;
   int                 new_num_periodic;

   hypre_Box          *box;
   hypre_Box          *local_box;
   hypre_Box          *neighbor_box;
   hypre_Box          *local_cbox;
   hypre_Box          *neighbor_cbox;
   hypre_Index         imin;
   hypre_Index         imax;
   int                 alloc_size;

   double              perimeter_count, cperimeter_count;
   /*double              diff, distance, perimeter_count, cperimeter_count;*/
                      
   int                *iarray;
   int                *jrecv;
   int                 i, j, d, ilocal;
   int                 data_id, min_id, jj;

   /*-----------------------------------------
    * Copy needed info from fgrid
    *-----------------------------------------*/

   comm         = hypre_StructGridComm(fgrid);
   dim          = hypre_StructGridDim(fgrid);
   neighbors    = hypre_StructGridNeighbors(fgrid);
   hood_boxes   = hypre_BoxArrayDuplicate(hypre_BoxNeighborsBoxes(neighbors));
   num_hood     = hypre_BoxArraySize(hood_boxes);

   iarray  = hypre_BoxNeighborsProcs(neighbors);
   hood_procs = hypre_TAlloc(int, num_hood);
   for (i = 0; i < num_hood; i++)
   {
      hood_procs[i] = iarray[i];
   }

   iarray = hypre_BoxNeighborsIDs(neighbors);
   hood_ids  = hypre_TAlloc(int, num_hood);
   for (i = 0; i < num_hood; i++)
   {
      hood_ids[i] = iarray[i];
   }

   first_local  = hypre_BoxNeighborsFirstLocal(neighbors);
   num_local    = hypre_BoxNeighborsNumLocal(neighbors);
   num_periodic = hypre_BoxNeighborsNumPeriodic(neighbors);

   max_distance = hypre_StructGridMaxDistance(fgrid);
   bounding_box = hypre_BoxDuplicate(hypre_StructGridBoundingBox(fgrid));
   hypre_CopyIndex(hypre_StructGridPeriodic(fgrid), periodic);

   MPI_Comm_rank(comm, &my_rank);

#if DEBUG
   sprintf(filename, "zcoarsen.%05d", my_rank);

   if ((file = fopen(filename, "a")) == NULL)
   {
      printf("Error: can't open output file %s\n", filename);
      exit(1);
   }

   fprintf(file, "\n\n============================\n\n");
   fprintf(file, "\n\n%d\n\n", debug_count++);
   fprintf(file, "num_hood = %d\n", num_hood);
   for (i = 0; i < num_hood; i++)
   {
      box = hypre_BoxArrayBox(hood_boxes, i);
      fprintf(file, "(%d,%d,%d) X (%d,%d,%d) ; (%d,%d); %d\n",
              hypre_BoxIMinX(box),hypre_BoxIMinY(box),hypre_BoxIMinZ(box),
              hypre_BoxIMaxX(box),hypre_BoxIMaxY(box),hypre_BoxIMaxZ(box),
              hood_procs[i], hood_ids[i], hypre_BoxVolume(box));
   }
   fprintf(file, "first_local  = %d\n", first_local);
   fprintf(file, "num_local    = %d\n", num_local);
   fprintf(file, "num_periodic = %d\n", num_periodic);
#endif

   /*-----------------------------------------
    * Coarsen bounding box
    *-----------------------------------------*/

   hypre_StructCoarsenBox(bounding_box, index, stride);

   /*-----------------------------------------
    * Coarsen neighborhood boxes & determine
    * send / recv procs
    *
    * NOTE: Currently, this always communicates
    * with all neighboring processes.
    *-----------------------------------------*/

   local_cbox = hypre_BoxCreate();
   neighbor_cbox = hypre_BoxCreate();

   num_recvs = 0;
   num_sends = 0;
   recv_procs = NULL;
   send_procs = NULL;
   for (i = 0; i < num_hood; i++)
   {
      if (hood_procs[i] != my_rank)
      {
         for (j = 0; j < num_local; j++)
         {
            ilocal = first_local + j;

            local_box    = hypre_BoxArrayBox(hood_boxes, ilocal);
            neighbor_box = hypre_BoxArrayBox(hood_boxes, i);

            /* coarsen boxes being considered */
            hypre_CopyBox(local_box, local_cbox);
            hypre_StructCoarsenBox(local_cbox, index, stride);
            hypre_CopyBox(neighbor_box, neighbor_cbox);
            hypre_StructCoarsenBox(neighbor_cbox, index, stride);

            /*-----------------------
             * Receive info?
             *-----------------------*/

/* always communicate */
#if 0
            perimeter_count = 0;
            cperimeter_count = 0;
            for (d = 0; d < 3; d++)
            {
               distance = max_distance;
               diff = hypre_BoxIMaxD(neighbor_box, d) -
                  hypre_BoxIMaxD(local_box, d);
               if (diff > 0)
               {
                  distance = hypre_min(distance, diff);
               }
               diff = hypre_BoxIMinD(local_box, d) -
                  hypre_BoxIMinD(neighbor_box, d);
               if (diff > 0)
               {
                  distance = hypre_min(distance, diff);
               }
               if (distance < max_distance)
               {
                  perimeter_count++;
               }

               distance = max_distance;
               diff = hypre_BoxIMaxD(neighbor_cbox, d) -
                  hypre_BoxIMaxD(local_cbox, d);
               if (diff > 0)
               {
                  distance = hypre_min(distance, diff);
               }
               diff = hypre_BoxIMinD(local_cbox, d) -
                  hypre_BoxIMinD(neighbor_cbox, d);
               if (diff > 0)
               {
                  distance = hypre_min(distance, diff);
               }
               if (distance < max_distance)
               {
                  cperimeter_count++;
               }
            }
#else
            perimeter_count = 0;
            cperimeter_count = 1;
#endif
            if (cperimeter_count > perimeter_count)
            {
               if (num_recvs == 0)
               {
                  recv_procs = hypre_TAlloc(int, num_hood);
                  recv_procs[num_recvs] = hood_procs[i];
                  num_recvs++;
               }
               else if (hood_procs[i] != recv_procs[num_recvs-1])
               {
                  recv_procs[num_recvs] = hood_procs[i];
                  num_recvs++;
               }
            }

            /*-----------------------
             * Send info?
             *-----------------------*/

/* always communicate */
#if 0
            perimeter_count = 0;
            cperimeter_count = 0;
            for (d = 0; d < 3; d++)
            {
               distance = max_distance;
               diff = hypre_BoxIMaxD(local_box, d) -
                  hypre_BoxIMaxD(neighbor_box, d);
               if (diff > 0)
               {
                  distance = hypre_min(distance, diff);
               }
               diff = hypre_BoxIMinD(neighbor_box, d) -
                  hypre_BoxIMinD(local_box, d);
               if (diff > 0)
               {
                  distance = hypre_min(distance, diff);
               }
               if (distance < max_distance)
               {
                  perimeter_count++;
               }

               distance = max_distance;
               diff = hypre_BoxIMaxD(local_cbox, d) -
                  hypre_BoxIMaxD(neighbor_cbox, d);
               if (diff > 0)
               {
                  distance = hypre_min(distance, diff);
               }
               diff = hypre_BoxIMinD(neighbor_cbox, d) -
                  hypre_BoxIMinD(local_cbox, d);
               if (diff > 0)
               {
                  distance = hypre_min(distance, diff);
               }
               if (distance < max_distance)
               {
                  cperimeter_count++;
               }
            }
#else
            perimeter_count = 0;
            cperimeter_count = 1;
#endif
            if (cperimeter_count > perimeter_count)
            {
               if (num_sends == 0)
               {
                  send_procs = hypre_TAlloc(int, num_hood);
                  send_procs[num_sends] = hood_procs[i];
                  num_sends++;
               }
               else if (hood_procs[i] != send_procs[num_sends-1])
               {
                  send_procs[num_sends] = hood_procs[i];
                  num_sends++;
               }
            }