Пример #1
0
int
HYPRE_SStructGraphCreate( MPI_Comm             comm,
                          HYPRE_SStructGrid    grid,
                          HYPRE_SStructGraph  *graph_ptr )
{
   int  ierr = 0;

   hypre_SStructGraph     *graph;
   int                     nparts;
   hypre_SStructStencil ***stencils;
   hypre_SStructPGrid    **pgrids;
   int                     nvars;
   int                     part, var;

   graph = hypre_TAlloc(hypre_SStructGraph, 1);

   hypre_SStructGraphComm(graph) = comm;
   hypre_SStructGraphNDim(graph) = hypre_SStructGridNDim(grid);
   hypre_SStructGridRef(grid, &hypre_SStructGraphGrid(graph));
   nparts = hypre_SStructGridNParts(grid);
   hypre_SStructGraphNParts(graph) = nparts;
   pgrids = hypre_SStructGridPGrids(grid);
   hypre_SStructGraphPGrids(graph) = pgrids;
   stencils = hypre_TAlloc(hypre_SStructStencil **, nparts);
   for (part = 0; part < nparts; part++)
   {
      nvars = hypre_SStructPGridNVars(pgrids[part]);
      stencils[part] = hypre_TAlloc(hypre_SStructStencil *, nvars);
      for (var = 0; var < nvars; var++)
      {
         stencils[part][var] = NULL;
      }
   }
   hypre_SStructGraphStencils(graph) = stencils;

   hypre_SStructGraphNUVEntries(graph)  = 0;
   hypre_SStructGraphAUVEntries(graph)  = 0;
   hypre_SStructGraphIUVEntries(graph)  = NULL;

   hypre_SStructGraphUVEntries(graph)   = NULL;
   hypre_SStructGraphTotUEntries(graph) = 0;
   hypre_SStructGraphRefCount(graph)    = 1;
   hypre_SStructGraphObjectType(graph) = HYPRE_SSTRUCT;

   *graph_ptr = graph;

   return ierr;
}
Пример #2
0
HYPRE_Int
HYPRE_SStructGridDestroy( HYPRE_SStructGrid grid )
{
   HYPRE_Int                      nparts;
   hypre_SStructPGrid           **pgrids;
   HYPRE_Int                     *nneighbors;
   hypre_SStructNeighbor        **neighbors;
   hypre_Index                  **nbor_offsets;
   HYPRE_Int                    **nvneighbors;
   hypre_SStructNeighbor       ***vneighbors;
   hypre_SStructCommInfo        **vnbor_comm_info;
   HYPRE_Int                      vnbor_ncomms;
   HYPRE_Int                     *fem_nvars;
   HYPRE_Int                    **fem_vars;
   hypre_Index                  **fem_offsets;
   hypre_BoxManager            ***managers;
   hypre_BoxManager            ***nbor_managers;
   HYPRE_Int                      nvars;
   HYPRE_Int                      part, var, i;

   if (grid)
   {
      hypre_SStructGridRefCount(grid) --;
      if (hypre_SStructGridRefCount(grid) == 0)
      {
         nparts  = hypre_SStructGridNParts(grid);
         pgrids  = hypre_SStructGridPGrids(grid);
         nneighbors   = hypre_SStructGridNNeighbors(grid);
         neighbors    = hypre_SStructGridNeighbors(grid);
         nbor_offsets = hypre_SStructGridNborOffsets(grid);
         nvneighbors = hypre_SStructGridNVNeighbors(grid);
         vneighbors  = hypre_SStructGridVNeighbors(grid);
         vnbor_comm_info = hypre_SStructGridVNborCommInfo(grid);
         vnbor_ncomms = hypre_SStructGridVNborNComms(grid);
         fem_nvars   = hypre_SStructGridFEMNVars(grid);
         fem_vars    = hypre_SStructGridFEMVars(grid);
         fem_offsets = hypre_SStructGridFEMOffsets(grid);
         managers  = hypre_SStructGridBoxManagers(grid);
         nbor_managers  = hypre_SStructGridNborBoxManagers(grid);

         for (part = 0; part < nparts; part++)
         {
            nvars = hypre_SStructPGridNVars(pgrids[part]);
            for (var = 0; var < nvars; var++)
            {
               hypre_TFree(vneighbors[part][var]);
               hypre_BoxManDestroy(managers[part][var]);
               hypre_BoxManDestroy(nbor_managers[part][var]);
            }
            hypre_TFree(neighbors[part]);
            hypre_TFree(nbor_offsets[part]);
            hypre_TFree(nvneighbors[part]);
            hypre_TFree(vneighbors[part]);
            hypre_SStructPGridDestroy(pgrids[part]);
            hypre_TFree(fem_vars[part]);
            hypre_TFree(fem_offsets[part]);
            hypre_TFree(managers[part]);
            hypre_TFree(nbor_managers[part]);
         }
         for (i = 0; i < vnbor_ncomms; i++)
         {
            hypre_CommInfoDestroy(
               hypre_SStructCommInfoCommInfo(vnbor_comm_info[i]));
            hypre_TFree(vnbor_comm_info[i]);
         }
         hypre_TFree(vnbor_comm_info);
         hypre_TFree(pgrids);
         hypre_TFree(nneighbors);
         hypre_TFree(neighbors);
         hypre_TFree(nbor_offsets);
         hypre_TFree(fem_nvars);
         hypre_TFree(fem_vars);
         hypre_TFree(fem_offsets);
         hypre_TFree(nvneighbors);
         hypre_TFree(vneighbors);
         hypre_TFree(vnbor_comm_info);
         hypre_TFree(managers);
         hypre_TFree(nbor_managers);
         hypre_TFree(grid);
      }
   }

   return hypre_error_flag;
}
Пример #3
0
HYPRE_Int
HYPRE_SStructGridCreate( MPI_Comm           comm,
                         HYPRE_Int          ndim,
                         HYPRE_Int          nparts,
                         HYPRE_SStructGrid *grid_ptr )
{
   hypre_SStructGrid       *grid;
   hypre_SStructPGrid     **pgrids;
   hypre_SStructPGrid      *pgrid;
   HYPRE_Int               *nneighbors;
   hypre_SStructNeighbor  **neighbors;
   hypre_Index            **nbor_offsets;
   HYPRE_Int               *fem_nvars;
   HYPRE_Int              **fem_vars;
   hypre_Index            **fem_offsets;
   HYPRE_Int                i;

   grid = hypre_TAlloc(hypre_SStructGrid, 1);

   hypre_SStructGridComm(grid)   = comm;
   hypre_SStructGridNDim(grid)   = ndim;
   hypre_SStructGridNParts(grid) = nparts;
   pgrids = hypre_TAlloc(hypre_SStructPGrid *, nparts);
   nneighbors    = hypre_TAlloc(HYPRE_Int, nparts);
   neighbors     = hypre_TAlloc(hypre_SStructNeighbor *, nparts);
   nbor_offsets  = hypre_TAlloc(hypre_Index *, nparts);
   fem_nvars     = hypre_TAlloc(HYPRE_Int, nparts);
   fem_vars      = hypre_TAlloc(HYPRE_Int *, nparts);
   fem_offsets   = hypre_TAlloc(hypre_Index *, nparts);
   for (i = 0; i < nparts; i++)
   {
      hypre_SStructPGridCreate(comm, ndim, &pgrid);
      pgrids[i] = pgrid;
      nneighbors[i]    = 0;
      neighbors[i]     = NULL;
      nbor_offsets[i]  = NULL;
      fem_nvars[i]     = 0;
      fem_vars[i]      = NULL;
      fem_offsets[i]   = NULL;
   }
   hypre_SStructGridPGrids(grid)  = pgrids;
   hypre_SStructGridNNeighbors(grid)  = nneighbors;
   hypre_SStructGridNeighbors(grid)   = neighbors;
   hypre_SStructGridNborOffsets(grid) = nbor_offsets;
   hypre_SStructGridNUCVars(grid) = 0;
   hypre_SStructGridUCVars(grid)  = NULL;
   hypre_SStructGridFEMNVars(grid)   = fem_nvars;
   hypre_SStructGridFEMVars(grid)    = fem_vars;
   hypre_SStructGridFEMOffsets(grid) = fem_offsets;

   hypre_SStructGridBoxManagers(grid) = NULL;
   hypre_SStructGridNborBoxManagers(grid) = NULL;

   /* miscellaneous */
   hypre_SStructGridLocalSize(grid)     = 0;
   hypre_SStructGridGlobalSize(grid)    = 0;
   hypre_SStructGridRefCount(grid)      = 1;

   /* GEC0902 ghost addition to the grid    */
   hypre_SStructGridGhlocalSize(grid)   = 0; 

   *grid_ptr = grid;

   return hypre_error_flag;
}
Пример #4
0
/*--------------------------------------------------------------------------
 * 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);
   }
Пример #5
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);
   }
Пример #6
0
HYPRE_Int
HYPRE_SStructGraphCreate( MPI_Comm             comm,
                          HYPRE_SStructGrid    grid,
                          HYPRE_SStructGraph  *graph_ptr )
{
   hypre_SStructGraph     *graph;
   HYPRE_Int               nparts;
   hypre_SStructStencil ***stencils;
   hypre_SStructPGrid    **pgrids;
   HYPRE_Int              *fem_nsparse;
   HYPRE_Int             **fem_sparse_i;
   HYPRE_Int             **fem_sparse_j;
   HYPRE_Int             **fem_entries;
   HYPRE_Int               nvars;
   HYPRE_Int               part, var;

   graph = hypre_TAlloc(hypre_SStructGraph, 1);

   hypre_SStructGraphComm(graph) = comm;
   hypre_SStructGraphNDim(graph) = hypre_SStructGridNDim(grid);
   hypre_SStructGridRef(grid, &hypre_SStructGraphGrid(graph));
   hypre_SStructGridRef(grid, &hypre_SStructGraphDomainGrid(graph));
   nparts = hypre_SStructGridNParts(grid);
   hypre_SStructGraphNParts(graph) = nparts;
   pgrids = hypre_SStructGridPGrids(grid);
   stencils = hypre_TAlloc(hypre_SStructStencil **, nparts);
   fem_nsparse  = hypre_TAlloc(HYPRE_Int, nparts);
   fem_sparse_i = hypre_TAlloc(HYPRE_Int *, nparts);
   fem_sparse_j = hypre_TAlloc(HYPRE_Int *, nparts);
   fem_entries  = hypre_TAlloc(HYPRE_Int *, nparts);
   for (part = 0; part < nparts; part++)
   {
      nvars = hypre_SStructPGridNVars(pgrids[part]);
      stencils[part]  = hypre_TAlloc(hypre_SStructStencil *, nvars);
      fem_nsparse[part]  = 0;
      fem_sparse_i[part] = NULL;
      fem_sparse_j[part] = NULL;
      fem_entries[part]  = NULL;
      for (var = 0; var < nvars; var++)
      {
         stencils[part][var] = NULL;
      }
   }
   hypre_SStructGraphStencils(graph)   = stencils;
   hypre_SStructGraphFEMNSparse(graph) = fem_nsparse;
   hypre_SStructGraphFEMSparseJ(graph) = fem_sparse_i;
   hypre_SStructGraphFEMSparseI(graph) = fem_sparse_j;
   hypre_SStructGraphFEMEntries(graph) = fem_entries;

   hypre_SStructGraphNUVEntries(graph)  = 0;
   hypre_SStructGraphAUVEntries(graph)  = 0;
   hypre_SStructGraphIUVEntries(graph)  = NULL;

   hypre_SStructGraphUVEntries(graph)   = NULL;
   hypre_SStructGraphTotUEntries(graph) = 0;
   hypre_SStructGraphRefCount(graph)    = 1;
   hypre_SStructGraphObjectType(graph)  = HYPRE_SSTRUCT;

   hypre_SStructGraphEntries(graph)     = NULL;
   hypre_SStructNGraphEntries(graph)    = 0;
   hypre_SStructAGraphEntries(graph)    = 0;
   
   *graph_ptr = graph;

   return hypre_error_flag;
}