
/*** DO NOT EDIT THIS FILE DIRECTLY (use 'headers' to generate) ***/


#ifndef hypre_SSTRUCT_MV_HEADER
#define hypre_SSTRUCT_MV_HEADER

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include "HYPRE_sstruct_mv.h"
#include "_hypre_utilities.h"
#include "_hypre_struct_mv.h"
#include "_hypre_IJ_mv.h"

#ifdef HYPRE_MIXED_PRECISION
#include "_hypre_sstruct_mv_mup_def.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/******************************************************************************
 * Copyright (c) 1998 Lawrence Livermore National Security, LLC and other
 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 ******************************************************************************/

/******************************************************************************
 *
 * Header info for the hypre_SStructGrid structures
 *
 *****************************************************************************/

#ifndef hypre_SSTRUCT_GRID_HEADER
#define hypre_SSTRUCT_GRID_HEADER

/*--------------------------------------------------------------------------
 * hypre_SStructGrid:
 *
 * NOTE: Since variables may be replicated across different processes,
 * a separate set of "interface grids" is retained so that data can be
 * migrated onto and off of the internal (non-replicated) grids.
 *--------------------------------------------------------------------------*/

typedef HYPRE_Int hypre_SStructVariable;

typedef struct
{
   HYPRE_SStructVariable  type;
   HYPRE_Int              rank;     /* local rank */
   HYPRE_Int              proc;

} hypre_SStructUVar;

typedef struct
{
   HYPRE_Int              part;
   hypre_Index            cell;
   HYPRE_Int              nuvars;
   hypre_SStructUVar     *uvars;

} hypre_SStructUCVar;

typedef struct
{
   MPI_Comm                comm;             /* TODO: use different comms */
   HYPRE_Int               ndim;
   HYPRE_Int               nvars;            /* number of variables */
   HYPRE_SStructVariable  *vartypes;         /* types of variables */
   hypre_StructGrid       *sgrids[8];        /* struct grids for each vartype */
   hypre_BoxArray         *iboxarrays[8];    /* interface boxes */
   hypre_BoxArrayArray    *pbnd_boxaa[8];    /* arrays of box arrays for part boundaries
                                                each BoxArrayArray entry has size equal to
                                                the number of boxes in a sgrid */
   HYPRE_Int               active[8];        /* flag indicating if grid is active for mat/vec
                                                operations purposes */
   hypre_BoxArray         *pneighbors;
   hypre_Index            *pnbor_offsets;

   HYPRE_Int               local_size;       /* Number of variables locally */
   HYPRE_BigInt            global_size;      /* Total number of variables */

   HYPRE_Int               ref_count;

   hypre_Index             periodic;         /* Indicates if pgrid is periodic */

   /* GEC0902 additions for ghost expansion of boxes */
   // TODO: deprecate ghlocal_size
   HYPRE_Int               ghlocal_size;     /* Number of vars including ghosts */
   HYPRE_Int               cell_sgrid_done;  /* =1 implies cell grid already assembled */

   /* Geometrical data */
   HYPRE_Real              coords_origin[HYPRE_MAXDIM]; /* Origin coordinates */
   hypre_Index             coords_stride;

} hypre_SStructPGrid;

typedef struct
{
   hypre_Box    box;
   HYPRE_Int    part;
   hypre_Index  ilower; /* box ilower, but on the neighbor index-space */
   hypre_Index  coord;  /* lives on local index-space */
   hypre_Index  dir;    /* lives on local index-space */

} hypre_SStructNeighbor;

enum hypre_SStructBoxManInfoType
{
   hypre_SSTRUCT_BOXMAN_INFO_DEFAULT  = 0,
   hypre_SSTRUCT_BOXMAN_INFO_NEIGHBOR = 1
};

typedef struct
{
   HYPRE_Int     type;
   HYPRE_BigInt  offset;
   HYPRE_BigInt  ghoffset;

} hypre_SStructBoxManInfo;

typedef struct
{
   HYPRE_Int    type;
   HYPRE_BigInt offset;   /* minimum offset for this box */
   HYPRE_BigInt ghoffset; /* minimum offset ghost for this box */
   HYPRE_Int    proc;     /* redundant with the proc in the entry, but
                             makes some coding easier */
   HYPRE_Int    boxnum;   /* this is different from the entry id */
   HYPRE_Int    part;     /* part the box lives on */
   hypre_Index  ilower;   /* box ilower, but on the neighbor index-space */
   hypre_Index  coord;    /* lives on local index-space */
   hypre_Index  dir;      /* lives on local index-space */
   hypre_Index  stride;   /* lives on local index-space */
   hypre_Index  ghstride; /* the ghost equivalent of strides */

} hypre_SStructBoxManNborInfo;

typedef struct
{
   hypre_CommInfo  *comm_info;
   HYPRE_Int        send_part;
   HYPRE_Int        recv_part;
   HYPRE_Int        send_var;
   HYPRE_Int        recv_var;

} hypre_SStructCommInfo;

typedef struct hypre_SStructGrid_struct
{
   MPI_Comm                   comm;
   HYPRE_Int                  ndim;
   HYPRE_Int                  nparts;

   /* s-variable info */
   hypre_SStructPGrid       **pgrids;

   /* neighbor info */
   HYPRE_Int                 *nneighbors;
   hypre_SStructNeighbor    **neighbors;
   hypre_Index              **nbor_offsets;
   HYPRE_Int                **nvneighbors;
   hypre_SStructNeighbor   ***vneighbors;
   hypre_SStructCommInfo    **vnbor_comm_info; /* for updating shared data */
   HYPRE_Int                  vnbor_ncomms;

   /* u-variables info: During construction, array entries are consecutive.
    * After 'Assemble', entries are referenced via local cell rank. */
   HYPRE_Int                  nucvars;
   hypre_SStructUCVar       **ucvars;

   /* info for fem-based user input (for each part) */
   HYPRE_Int                 *fem_nvars;
   HYPRE_Int                **fem_vars;
   hypre_Index              **fem_offsets;

   /* info for mapping (part, index, var) --> rank */
   hypre_BoxManager        ***boxmans;      /* manager for each part, var */
   hypre_BoxManager        ***nbor_boxmans; /* manager for each part, var */

   HYPRE_BigInt               start_rank;

   HYPRE_Int                  local_size;  /* Number of variables locally */
   HYPRE_BigInt               global_size; /* Total number of variables */

   HYPRE_Int                  ref_count;

   /* GEC0902 additions for ghost expansion of boxes */
   // TODO: deprecate these ones. SStructMatrix should hold these data instead
   HYPRE_Int               ghlocal_size;  /* GEC0902 Number of vars including ghosts */
   HYPRE_BigInt            ghstart_rank;  /* GEC0902 start rank including ghosts  */

} hypre_SStructGrid;

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructGrid
 *--------------------------------------------------------------------------*/

#define hypre_SStructGridComm(grid)           ((grid) -> comm)
#define hypre_SStructGridNDim(grid)           ((grid) -> ndim)
#define hypre_SStructGridNParts(grid)         ((grid) -> nparts)
#define hypre_SStructGridPGrids(grid)         ((grid) -> pgrids)
#define hypre_SStructGridPGrid(grid, part)    ((grid) -> pgrids[part])
#define hypre_SStructGridNNeighbors(grid)     ((grid) -> nneighbors)
#define hypre_SStructGridNeighbors(grid)      ((grid) -> neighbors)
#define hypre_SStructGridNborOffsets(grid)    ((grid) -> nbor_offsets)
#define hypre_SStructGridNVNeighbors(grid)    ((grid) -> nvneighbors)
#define hypre_SStructGridVNeighbors(grid)     ((grid) -> vneighbors)
#define hypre_SStructGridVNborCommInfo(grid)  ((grid) -> vnbor_comm_info)
#define hypre_SStructGridVNborNComms(grid)    ((grid) -> vnbor_ncomms)
#define hypre_SStructGridNUCVars(grid)        ((grid) -> nucvars)
#define hypre_SStructGridUCVars(grid)         ((grid) -> ucvars)
#define hypre_SStructGridUCVar(grid, i)       ((grid) -> ucvars[i])

#define hypre_SStructGridFEMNVars(grid)       ((grid) -> fem_nvars)
#define hypre_SStructGridFEMVars(grid)        ((grid) -> fem_vars)
#define hypre_SStructGridFEMOffsets(grid)     ((grid) -> fem_offsets)
#define hypre_SStructGridFEMPNVars(grid, part)   ((grid) -> fem_nvars[part])
#define hypre_SStructGridFEMPVars(grid, part)    ((grid) -> fem_vars[part])
#define hypre_SStructGridFEMPOffsets(grid, part) ((grid) -> fem_offsets[part])

#define hypre_SStructGridBoxManagers(grid)           ((grid) -> boxmans)
#define hypre_SStructGridBoxManager(grid, part, var) ((grid) -> boxmans[part][var])

#define hypre_SStructGridNborBoxManagers(grid)           ((grid) -> nbor_boxmans)
#define hypre_SStructGridNborBoxManager(grid, part, var) ((grid) -> nbor_boxmans[part][var])

#define hypre_SStructGridStartRank(grid)      ((grid) -> start_rank)
#define hypre_SStructGridLocalSize(grid)      ((grid) -> local_size)
#define hypre_SStructGridGlobalSize(grid)     ((grid) -> global_size)
#define hypre_SStructGridRefCount(grid)       ((grid) -> ref_count)
#define hypre_SStructGridGhlocalSize(grid)    ((grid) -> ghlocal_size)
#define hypre_SStructGridGhstartRank(grid)    ((grid) -> ghstart_rank)

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructPGrid
 *--------------------------------------------------------------------------*/

#define hypre_SStructPGridComm(pgrid)             ((pgrid) -> comm)
#define hypre_SStructPGridNDim(pgrid)             ((pgrid) -> ndim)
#define hypre_SStructPGridNVars(pgrid)            ((pgrid) -> nvars)
#define hypre_SStructPGridVarTypes(pgrid)         ((pgrid) -> vartypes)
#define hypre_SStructPGridVarType(pgrid, var)     ((pgrid) -> vartypes[var])
#define hypre_SStructPGridCellSGridDone(pgrid)    ((pgrid) -> cell_sgrid_done)
#define hypre_SStructPGridCoordsOrigin(pgrid)     ((pgrid) -> coords_origin)
#define hypre_SStructPGridCoordsStride(pgrid)     ((pgrid) -> coords_stride)

#define hypre_SStructPGridSGrids(pgrid)           ((pgrid) -> sgrids)
#define hypre_SStructPGridSGrid(pgrid, var) \
((pgrid) -> sgrids[hypre_SStructPGridVarType(pgrid, var)])
#define hypre_SStructPGridCellSGrid(pgrid) \
((pgrid) -> sgrids[HYPRE_SSTRUCT_VARIABLE_CELL])
#define hypre_SStructPGridVTSGrid(pgrid, vartype) ((pgrid) -> sgrids[vartype])

#define hypre_SStructPGridIBoxArrays(pgrid)       ((pgrid) -> iboxarrays)
#define hypre_SStructPGridIBoxArray(pgrid, var) \
((pgrid) -> iboxarrays[hypre_SStructPGridVarType(pgrid, var)])
#define hypre_SStructPGridCellIBoxArray(pgrid) \
((pgrid) -> iboxarrays[HYPRE_SSTRUCT_VARIABLE_CELL])
#define hypre_SStructPGridVTIBoxArray(pgrid, vartype) \
((pgrid) -> iboxarrays[vartype])
#define hypre_SStructPGridPBndBoxArrayArrays(pgrid)    ((pgrid) -> pbnd_boxaa)
#define hypre_SStructPGridPBndBoxArrayArray(pgrid, var) \
((pgrid) -> pbnd_boxaa[hypre_SStructPGridVarType(pgrid, var)])
#define hypre_SStructPGridVTPBndBoxArrayArray(pgrid, vartype) \
((pgrid) -> pbnd_boxaa[vartype])

#define hypre_SStructPGridActive(pgrid, var) \
((pgrid) -> active[hypre_SStructPGridVarType(pgrid, var)])
#define hypre_SStructPGridVTActive(pgrid, vart)   ((pgrid) -> active[vart])
#define hypre_SStructPGridPNeighbors(pgrid)       ((pgrid) -> pneighbors)
#define hypre_SStructPGridPNborOffsets(pgrid)     ((pgrid) -> pnbor_offsets)
#define hypre_SStructPGridLocalSize(pgrid)        ((pgrid) -> local_size)
#define hypre_SStructPGridGlobalSize(pgrid)       ((pgrid) -> global_size)
#define hypre_SStructPGridRefCount(pgrid)         ((pgrid) -> ref_count)
#define hypre_SStructPGridPeriodic(pgrid)         ((pgrid) -> periodic)
#define hypre_SStructPGridGhlocalSize(pgrid)      ((pgrid) -> ghlocal_size)

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructBoxManInfo
 *--------------------------------------------------------------------------*/

#define hypre_SStructBoxManInfoType(info)            ((info) -> type)
#define hypre_SStructBoxManInfoOffset(info)          ((info) -> offset)
#define hypre_SStructBoxManInfoGhoffset(info)        ((info) -> ghoffset)

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructBoxManInfo
 *--------------------------------------------------------------------------*/

/* Use the MapInfo macros to access the first three structure components */
#define hypre_SStructBoxManNborInfoProc(info)    ((info) -> proc)
#define hypre_SStructBoxManNborInfoBoxnum(info)  ((info) -> boxnum)
#define hypre_SStructBoxManNborInfoPart(info)    ((info) -> part)
#define hypre_SStructBoxManNborInfoILower(info)  ((info) -> ilower)
#define hypre_SStructBoxManNborInfoCoord(info)   ((info) -> coord)
#define hypre_SStructBoxManNborInfoDir(info)     ((info) -> dir)
#define hypre_SStructBoxManNborInfoStride(info)  ((info) -> stride)
#define hypre_SStructBoxManNborInfoGhstride(info)  ((info) -> ghstride)

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructNeighbor
 *--------------------------------------------------------------------------*/

#define hypre_SStructNeighborBox(neighbor)    &((neighbor) -> box)
#define hypre_SStructNeighborPart(neighbor)    ((neighbor) -> part)
#define hypre_SStructNeighborILower(neighbor)  ((neighbor) -> ilower)
#define hypre_SStructNeighborCoord(neighbor)   ((neighbor) -> coord)
#define hypre_SStructNeighborDir(neighbor)     ((neighbor) -> dir)

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructCommInfo
 *--------------------------------------------------------------------------*/

#define hypre_SStructCommInfoCommInfo(cinfo)  ((cinfo) -> comm_info)
#define hypre_SStructCommInfoSendPart(cinfo)  ((cinfo) -> send_part)
#define hypre_SStructCommInfoRecvPart(cinfo)  ((cinfo) -> recv_part)
#define hypre_SStructCommInfoSendVar(cinfo)   ((cinfo) -> send_var)
#define hypre_SStructCommInfoRecvVar(cinfo)   ((cinfo) -> recv_var)

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructUCVar
 *--------------------------------------------------------------------------*/

#define hypre_SStructUCVarPart(uc)     ((uc) -> part)
#define hypre_SStructUCVarCell(uc)     ((uc) -> cell)
#define hypre_SStructUCVarNUVars(uc)   ((uc) -> nuvars)
#define hypre_SStructUCVarUVars(uc)    ((uc) -> uvars)
#define hypre_SStructUCVarType(uc, i)  ((uc) -> uvars[i].type)
#define hypre_SStructUCVarRank(uc, i)  ((uc) -> uvars[i].rank)
#define hypre_SStructUCVarProc(uc, i)  ((uc) -> uvars[i].proc)

#endif
/******************************************************************************
 * Copyright (c) 1998 Lawrence Livermore National Security, LLC and other
 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 ******************************************************************************/

/******************************************************************************
 *
 * Header info for hypre_SStructStencil data structures
 *
 *****************************************************************************/

#ifndef hypre_SSTRUCT_STENCIL_HEADER
#define hypre_SSTRUCT_STENCIL_HEADER

/*--------------------------------------------------------------------------
 * hypre_SStructStencil
 *--------------------------------------------------------------------------*/

typedef struct hypre_SStructStencil_struct
{
   hypre_StructStencil  *sstencil;
   HYPRE_Int            *vars;

   HYPRE_Int             ref_count;

} hypre_SStructStencil;

/*--------------------------------------------------------------------------
 * Accessor functions for the hypre_SStructStencil structure
 *--------------------------------------------------------------------------*/

#define hypre_SStructStencilSStencil(stencil)     ((stencil) -> sstencil)
#define hypre_SStructStencilVars(stencil)         ((stencil) -> vars)
#define hypre_SStructStencilVar(stencil, i)       ((stencil) -> vars[i])
#define hypre_SStructStencilRefCount(stencil)     ((stencil) -> ref_count)

#define hypre_SStructStencilShape(stencil) \
hypre_StructStencilShape( hypre_SStructStencilSStencil(stencil) )
#define hypre_SStructStencilSize(stencil) \
hypre_StructStencilSize( hypre_SStructStencilSStencil(stencil) )
#define hypre_SStructStencilNDim(stencil) \
hypre_StructStencilNDim( hypre_SStructStencilSStencil(stencil) )
#define hypre_SStructStencilOffset(stencil, i) \
hypre_StructStencilOffset( hypre_SStructStencilSStencil(stencil), i )

#endif
/******************************************************************************
 * Copyright (c) 1998 Lawrence Livermore National Security, LLC and other
 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 ******************************************************************************/

/******************************************************************************
 *
 * Header info for the hypre_SStructGraph structures
 *
 *****************************************************************************/

#ifndef hypre_SSTRUCT_GRAPH_HEADER
#define hypre_SSTRUCT_GRAPH_HEADER

/*--------------------------------------------------------------------------
 * hypre_SStructGraph:
 *--------------------------------------------------------------------------*/

typedef struct
{
   HYPRE_Int     part;
   hypre_Index   index;
   HYPRE_Int     var;
   HYPRE_Int     to_part;
   hypre_Index   to_index;
   HYPRE_Int     to_var;

} hypre_SStructGraphEntry;

typedef struct
{
   HYPRE_Int     to_part;
   hypre_Index   to_index;
   HYPRE_Int     to_var;
   HYPRE_Int     to_boxnum;      /* local box number */
   HYPRE_Int     to_proc;
   HYPRE_BigInt  to_rank;

} hypre_SStructUEntry;

typedef struct
{
   HYPRE_Int            part;
   hypre_Index          index;
   HYPRE_Int            var;
   HYPRE_BigInt         rank;
   HYPRE_Int            nUentries;
   hypre_SStructUEntry *Uentries;

} hypre_SStructUVEntry;

typedef struct hypre_SStructGraph_struct
{
   MPI_Comm                comm;
   HYPRE_Int               ndim;
   HYPRE_Int               nparts;   /* number of parts */
   hypre_SStructGrid      *grid;     /* base grid */
   hypre_SStructGrid      *dom_grid; /* domain grid */
   hypre_SStructStencil ***stencils; /* each (part, var) has a stencil */

   /* Info for fem-based user input */
   HYPRE_Int              *fem_nsparse;
   HYPRE_Int             **fem_sparse_i;
   HYPRE_Int             **fem_sparse_j;
   HYPRE_Int             **fem_entries;

   /* U-graph info: Entries are referenced via a local rank that comes from an
    * ordering of the local grid boxes with ghost zones added. */
   HYPRE_Int               nUventries; /* number of Uventries */
   HYPRE_BigInt           *iUventries; /* rank indexes into Uventries */
   hypre_SStructUVEntry  **Uventries;
   HYPRE_Int               Uvesize;    /* size of Uventries array */
   HYPRE_Int               Uemaxsize;  /* max size of Uentries */
   HYPRE_BigInt          **Uveoffsets; /* offsets for computing rank indexes */
   hypre_Box            ***Uvboxes;    /* (part, var) array of boxes for non-stencil entries */

   /* These are created in GraphAddEntries() then deleted in GraphAssemble() */
   hypre_SStructGraphEntry **graph_entries;
   HYPRE_Int               n_graph_entries; /* number graph entries */
   HYPRE_Int               a_graph_entries; /* alloced graph entries */

   /* Object data */
   HYPRE_Int               ref_count;
   HYPRE_Int               type;
} hypre_SStructGraph;

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructGraph
 *--------------------------------------------------------------------------*/

#define hypre_SStructGraphComm(graph)           ((graph) -> comm)
#define hypre_SStructGraphNDim(graph)           ((graph) -> ndim)
#define hypre_SStructGraphGrid(graph)           ((graph) -> grid)
#define hypre_SStructGraphDomGrid(graph)        ((graph) -> dom_grid)
#define hypre_SStructGraphPGrids(graph) \
   hypre_SStructGridPGrids(hypre_SStructGraphGrid(graph))
#define hypre_SStructGraphPGrid(graph, p) \
   hypre_SStructGridPGrid(hypre_SStructGraphGrid(graph), p)
#define hypre_SStructGraphStencils(graph)       ((graph) -> stencils)
#define hypre_SStructGraphStencil(graph, p, v)  ((graph) -> stencils[p][v])
#define hypre_SStructGraphNParts(graph)         ((graph) -> nparts)

#define hypre_SStructGraphFEMNSparse(graph)     ((graph) -> fem_nsparse)
#define hypre_SStructGraphFEMSparseI(graph)     ((graph) -> fem_sparse_i)
#define hypre_SStructGraphFEMSparseJ(graph)     ((graph) -> fem_sparse_j)
#define hypre_SStructGraphFEMEntries(graph)     ((graph) -> fem_entries)
#define hypre_SStructGraphFEMPNSparse(graph, p) ((graph) -> fem_nsparse[p])
#define hypre_SStructGraphFEMPSparseI(graph, p) ((graph) -> fem_sparse_i[p])
#define hypre_SStructGraphFEMPSparseJ(graph, p) ((graph) -> fem_sparse_j[p])
#define hypre_SStructGraphFEMPEntries(graph, p) ((graph) -> fem_entries[p])

#define hypre_SStructGraphNUVEntries(graph)     ((graph) -> nUventries)
#define hypre_SStructGraphIUVEntries(graph)     ((graph) -> iUventries)
#define hypre_SStructGraphIUVEntry(graph, i)    ((graph) -> iUventries[i])
#define hypre_SStructGraphUVEntries(graph)      ((graph) -> Uventries)
#define hypre_SStructGraphUVEntry(graph, i)     ((graph) -> Uventries[i])
#define hypre_SStructGraphUVESize(graph)        ((graph) -> Uvesize)
#define hypre_SStructGraphUEMaxSize(graph)      ((graph) -> Uemaxsize)
#define hypre_SStructGraphUVEOffsets(graph)     ((graph) -> Uveoffsets)
#define hypre_SStructGraphUVEOffset(graph, p, v)((graph) -> Uveoffsets[p][v])
#define hypre_SStructGraphUVBoxes(graph)        ((graph) -> Uvboxes)
#define hypre_SStructGraphUVBox(graph, p, v)    ((graph) -> Uvboxes[p][v])

#define hypre_SStructGraphEntries(graph)        ((graph) -> graph_entries)
#define hypre_SStructNGraphEntries(graph)       ((graph) -> n_graph_entries)
#define hypre_SStructAGraphEntries(graph)       ((graph) -> a_graph_entries)
#define hypre_SStructGraphRefCount(graph)       ((graph) -> ref_count)
#define hypre_SStructGraphObjectType(graph)     ((graph) -> type)

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructUVEntry
 *--------------------------------------------------------------------------*/

#define hypre_SStructUVEntryPart(Uv)        ((Uv) -> part)
#define hypre_SStructUVEntryIndex(Uv)       ((Uv) -> index)
#define hypre_SStructUVEntryVar(Uv)         ((Uv) -> var)
#define hypre_SStructUVEntryRank(Uv)        ((Uv) -> rank)
#define hypre_SStructUVEntryNUEntries(Uv)   ((Uv) -> nUentries)
#define hypre_SStructUVEntryUEntries(Uv)    ((Uv) -> Uentries)
#define hypre_SStructUVEntryUEntry(Uv, i)  &((Uv) -> Uentries[i])
#define hypre_SStructUVEntryToPart(Uv, i)   ((Uv) -> Uentries[i].to_part)
#define hypre_SStructUVEntryToIndex(Uv, i)  ((Uv) -> Uentries[i].to_index)
#define hypre_SStructUVEntryToVar(Uv, i)    ((Uv) -> Uentries[i].to_var)
#define hypre_SStructUVEntryToBoxnum(Uv, i) ((Uv) -> Uentries[i].to_boxnum)
#define hypre_SStructUVEntryToProc(Uv, i)   ((Uv) -> Uentries[i].to_proc)
#define hypre_SStructUVEntryToRank(Uv, i)   ((Uv) -> Uentries[i].to_rank)

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructUEntry
 *--------------------------------------------------------------------------*/

#define hypre_SStructUEntryToPart(U)   ((U) -> to_part)
#define hypre_SStructUEntryToIndex(U)  ((U) -> to_index)
#define hypre_SStructUEntryToVar(U)    ((U) -> to_var)
#define hypre_SStructUEntryToBoxnum(U) ((U) -> to_boxnum)
#define hypre_SStructUEntryToProc(U)   ((U) -> to_proc)
#define hypre_SStructUEntryToRank(U)   ((U) -> to_rank)

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructGraphEntry
 *--------------------------------------------------------------------------*/

#define hypre_SStructGraphEntryPart(g)     ((g) -> part)
#define hypre_SStructGraphEntryIndex(g)    ((g) -> index)
#define hypre_SStructGraphEntryVar(g)      ((g) -> var)
#define hypre_SStructGraphEntryToPart(g)   ((g) -> to_part)
#define hypre_SStructGraphEntryToIndex(g)  ((g) -> to_index)
#define hypre_SStructGraphEntryToVar(g)    ((g) -> to_var)

#endif
/******************************************************************************
 * Copyright (c) 1998 Lawrence Livermore National Security, LLC and other
 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 ******************************************************************************/

/******************************************************************************
 *
 * Header info for the hypre_SStructMatrix structures
 *
 *****************************************************************************/

#ifndef hypre_SSTRUCT_MATRIX_HEADER
#define hypre_SSTRUCT_MATRIX_HEADER

/*--------------------------------------------------------------------------
 * hypre_SStructMatrix:
 *--------------------------------------------------------------------------*/

typedef struct hypre_SStructPMatrix_struct
{
   MPI_Comm                comm;
   hypre_SStructPGrid     *pgrid;
   hypre_SStructStencil  **stencils;     /* nvar array of stencils */

   HYPRE_Int               nvars;
   HYPRE_Int             **smaps;
   hypre_StructStencil  ***sstencils;    /* nvar x nvar array of sstencils */
   hypre_StructMatrix   ***smatrices;    /* nvar x nvar array of smatrices */
   HYPRE_Int             **symmetric;    /* Stencil entries symmetric?
                                          * (nvar x nvar array) */
   HYPRE_Int             **num_centries; /* (nvar x nvar) array */
   HYPRE_Int            ***centries;     /* (nvar x nvar x sentries_size) array constant entries */
   hypre_Index             dom_stride;   /* domain grid stride */
   hypre_Index             ran_stride;   /* range grid stride */

   /* temporary storage for SetValues routines */
   HYPRE_Int               sentries_size;
   HYPRE_Int              *sentries;

   HYPRE_Int               accumulated;  /* AddTo values accumulated? */

   HYPRE_Int               ref_count;

} hypre_SStructPMatrix;

/*--------------------------------------------------------------------------
 * hypre_SStructMatrix:
 *
 * - Storage of parts id dictated by the coarse grid
 *--------------------------------------------------------------------------*/

typedef struct hypre_SStructMatrix_struct
{
   MPI_Comm                comm;
   HYPRE_Int               ndim;
   HYPRE_Int            ***splits;        /* S/U-matrix split for each stencil */
   hypre_SStructGraph     *graph;

   /* S-matrix info */
   HYPRE_Int               nparts;
   hypre_SStructPMatrix  **pmatrices;
   HYPRE_Int            ***symmetric;    /* Stencil entries symmetric?
                                          * (nparts x nvar x nvar array) */
   HYPRE_Int            ***num_centries; /* (nparts x nvar x nvar) array */
   HYPRE_Int           ****centries;     /* (nparts x nvar x nvar x entries_size) array */
   hypre_Index            *dom_stride;   /* (nparts) array of domain stride */
   hypre_Index            *ran_stride;   /* (nparts) array of range stride */

   /* U-matrix info */
   HYPRE_IJMatrix          ijmatrix;
   hypre_ParCSRMatrix     *parcsrmatrix;

   /* temporary storage for SetValues routines */
   HYPRE_Int               entries_size;
   HYPRE_Int              *Sentries;
   HYPRE_Int              *Uentries;
   HYPRE_Int               tmp_size;     /* size of the following 3 */
   HYPRE_BigInt           *tmp_row_coords;
   HYPRE_BigInt           *tmp_col_coords;
   HYPRE_Complex          *tmp_coeffs;
   HYPRE_BigInt           *d_tmp_row_coords;
   HYPRE_BigInt           *d_tmp_col_coords;
   HYPRE_Complex          *d_tmp_coeffs;

   HYPRE_Int               ns_symmetric; /* Non-stencil entries symmetric? */
   HYPRE_Int               global_size;  /* Total number of nonzero coeffs */

   HYPRE_Int               ref_count;

   /* GEC0902   adding an object type to the matrix  */
   HYPRE_Int               object_type;

} hypre_SStructMatrix;

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructMatrix
 *--------------------------------------------------------------------------*/

#define hypre_SStructMatrixComm(mat)                ((mat) -> comm)
#define hypre_SStructMatrixNDim(mat)                ((mat) -> ndim)
#define hypre_SStructMatrixGraph(mat)               ((mat) -> graph)
#define hypre_SStructMatrixSplits(mat)              ((mat) -> splits)
#define hypre_SStructMatrixSplit(mat, p, v)         ((mat) -> splits[p][v])
#define hypre_SStructMatrixNParts(mat)              ((mat) -> nparts)
#define hypre_SStructMatrixPMatrices(mat)           ((mat) -> pmatrices)
#define hypre_SStructMatrixPMatrix(mat, part)       ((mat) -> pmatrices[part])
#define hypre_SStructMatrixSymmetric(mat)           ((mat) -> symmetric)
#define hypre_SStructMatrixNumCEntries(mat)         ((mat) -> num_centries)
#define hypre_SStructMatrixCEntries(mat)            ((mat) -> centries)
#define hypre_SStructMatrixDomainStride(mat)        ((mat) -> dom_stride)
#define hypre_SStructMatrixRangeStride(mat)         ((mat) -> ran_stride)
#define hypre_SStructMatrixIJMatrix(mat)            ((mat) -> ijmatrix)
#define hypre_SStructMatrixParCSRMatrix(mat)        ((mat) -> parcsrmatrix)
#define hypre_SStructMatrixEntriesSize(mat)         ((mat) -> entries_size)
#define hypre_SStructMatrixSEntries(mat)            ((mat) -> Sentries)
#define hypre_SStructMatrixUEntries(mat)            ((mat) -> Uentries)
#define hypre_SStructMatrixTmpSize(mat)             ((mat) -> tmp_size)
#define hypre_SStructMatrixTmpRowCoords(mat)        ((mat) -> tmp_row_coords)
#define hypre_SStructMatrixTmpColCoords(mat)        ((mat) -> tmp_col_coords)
#define hypre_SStructMatrixTmpCoeffs(mat)           ((mat) -> tmp_coeffs)
#define hypre_SStructMatrixTmpRowCoordsDevice(mat)  ((mat) -> d_tmp_row_coords)
#define hypre_SStructMatrixTmpColCoordsDevice(mat)  ((mat) -> d_tmp_col_coords)
#define hypre_SStructMatrixTmpCoeffsDevice(mat)     ((mat) -> d_tmp_coeffs)
#define hypre_SStructMatrixNSSymmetric(mat)         ((mat) -> ns_symmetric)
#define hypre_SStructMatrixGlobalSize(mat)          ((mat) -> global_size)
#define hypre_SStructMatrixRefCount(mat)            ((mat) -> ref_count)
#define hypre_SStructMatrixObjectType(mat)          ((mat) -> object_type)

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructPMatrix
 *--------------------------------------------------------------------------*/

#define hypre_SStructPMatrixComm(pmat)              ((pmat) -> comm)
#define hypre_SStructPMatrixPGrid(pmat)             ((pmat) -> pgrid)
#define hypre_SStructPMatrixNDim(pmat)              hypre_SStructPGridNDim((pmat) -> pgrid)
#define hypre_SStructPMatrixStencils(pmat)          ((pmat) -> stencils)
#define hypre_SStructPMatrixNVars(pmat)             ((pmat) -> nvars)
#define hypre_SStructPMatrixStencil(pmat, var)      ((pmat) -> stencils[var])
#define hypre_SStructPMatrixSMaps(pmat)             ((pmat) -> smaps)
#define hypre_SStructPMatrixSMap(pmat, var)         ((pmat) -> smaps[var])
#define hypre_SStructPMatrixSStencils(pmat)         ((pmat) -> sstencils)
#define hypre_SStructPMatrixSStencil(pmat, vi, vj)  ((pmat) -> sstencils[vi][vj])
#define hypre_SStructPMatrixSMatrices(pmat)         ((pmat) -> smatrices)
#define hypre_SStructPMatrixSMatrix(pmat, vi, vj)   ((pmat) -> smatrices[vi][vj])
#define hypre_SStructPMatrixSymmetric(pmat)         ((pmat) -> symmetric)
#define hypre_SStructPMatrixNumCEntries(pmat)       ((pmat) -> num_centries)
#define hypre_SStructPMatrixCEntries(pmat)          ((pmat) -> centries)
#define hypre_SStructPMatrixDomainStride(pmat)      ((pmat) -> dom_stride)
#define hypre_SStructPMatrixRangeStride(pmat)       ((pmat) -> ran_stride)
#define hypre_SStructPMatrixSEntriesSize(pmat)      ((pmat) -> sentries_size)
#define hypre_SStructPMatrixSEntries(pmat)          ((pmat) -> sentries)
#define hypre_SStructPMatrixAccumulated(pmat)       ((pmat) -> accumulated)
#define hypre_SStructPMatrixRefCount(pmat)          ((pmat) -> ref_count)

#endif
/******************************************************************************
 * Copyright (c) 1998 Lawrence Livermore National Security, LLC and other
 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 ******************************************************************************/

/******************************************************************************
 *
 * Header info for the hypre_SStructVector structures
 *
 *****************************************************************************/

#ifndef hypre_SSTRUCT_VECTOR_HEADER
#define hypre_SSTRUCT_VECTOR_HEADER

/*--------------------------------------------------------------------------
 * hypre_SStructVector:
 *--------------------------------------------------------------------------*/

typedef struct
{
   MPI_Comm                comm;
   hypre_SStructPGrid     *pgrid;

   HYPRE_Int               nvars;
   hypre_StructVector    **svectors;    /* nvar array of svectors */
   hypre_CommPkg         **comm_pkgs;   /* nvar array of comm pkgs */

   HYPRE_Int               accumulated; /* AddTo values accumulated? */

   HYPRE_Int               ref_count;

   HYPRE_Int              *dataindices; /* dataindices[p]: start index of data for var v */
   HYPRE_Int               datasize;    /* Size of the pvector = sums size of svectors */

} hypre_SStructPVector;

typedef struct hypre_SStructVector_struct
{
   MPI_Comm                comm;
   HYPRE_Int               ndim;
   hypre_SStructGrid      *grid;
   HYPRE_Int               object_type;

   /* s-vector info */
   HYPRE_Int               nparts;
   hypre_SStructPVector  **pvectors;

   /* u-vector info */
   HYPRE_IJVector          ijvector;
   hypre_ParVector        *parvector;

   /* inter-part communication info */
   HYPRE_Int               nbor_ncomms;  /* num comm_pkgs with neighbor parts */

   /* Pointer to big chunk of memory and auxiliary information */
   HYPRE_Complex          *data;        /* GEC1002 pointer to chunk data */
   HYPRE_Int              *dataindices; /* dataindices[p]: start index of data for part p */
   HYPRE_Int               datasize;    /* size of all data = ghlocalsize */

   HYPRE_Int               global_size;  /* Total number coefficients */
   HYPRE_Int               ref_count;

} hypre_SStructVector;

/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructVector
 *--------------------------------------------------------------------------*/

#define hypre_SStructVectorComm(vec)            ((vec) -> comm)
#define hypre_SStructVectorNDim(vec)            ((vec) -> ndim)
#define hypre_SStructVectorGrid(vec)            ((vec) -> grid)
#define hypre_SStructVectorObjectType(vec)      ((vec) -> object_type)
#define hypre_SStructVectorNParts(vec)          ((vec) -> nparts)
#define hypre_SStructVectorPVectors(vec)        ((vec) -> pvectors)
#define hypre_SStructVectorPVector(vec, part)   ((vec) -> pvectors[part])
#define hypre_SStructVectorIJVector(vec)        ((vec) -> ijvector)
#define hypre_SStructVectorParVector(vec)       ((vec) -> parvector)
#define hypre_SStructVectorNborNComms(vec)      ((vec) -> nbor_ncomms)
#define hypre_SStructVectorGlobalSize(vec)      ((vec) -> global_size)
#define hypre_SStructVectorRefCount(vec)        ((vec) -> ref_count)
#define hypre_SStructVectorData(vec)            ((vec) -> data )
#define hypre_SStructVectorDataIndices(vec)     ((vec) -> dataindices)
#define hypre_SStructVectorDataIndex(vec, part) ((vec) -> dataindices[part])
#define hypre_SStructVectorDataSize(vec)        ((vec) -> datasize)


/*--------------------------------------------------------------------------
 * Accessor macros: hypre_SStructPVector
 *--------------------------------------------------------------------------*/

#define hypre_SStructPVectorComm(pvec)         ((pvec) -> comm)
#define hypre_SStructPVectorPGrid(pvec)        ((pvec) -> pgrid)
#define hypre_SStructPVectorNVars(pvec)        ((pvec) -> nvars)
#define hypre_SStructPVectorSVectors(pvec)     ((pvec) -> svectors)
#define hypre_SStructPVectorSVector(pvec, v)   ((pvec) -> svectors[v])
#define hypre_SStructPVectorCommPkgs(pvec)     ((pvec) -> comm_pkgs)
#define hypre_SStructPVectorCommPkg(pvec, v)   ((pvec) -> comm_pkgs[v])
#define hypre_SStructPVectorAccumulated(pvec)  ((pvec) -> accumulated)
#define hypre_SStructPVectorRefCount(pvec)     ((pvec) -> ref_count)
#define hypre_SStructPVectorDataIndices(pvec)  ((pvec) -> dataindices)
#define hypre_SStructPVectorDataIndex(pvec, v) ((pvec) -> dataindices[v])
#define hypre_SStructPVectorDataSize(pvec)     ((pvec) -> datasize)

#endif
/******************************************************************************
 * Copyright (c) 1998 Lawrence Livermore National Security, LLC and other
 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 ******************************************************************************/

/******************************************************************************
 *
 * Header info for the semi-structured matrix/matrix multiplication structures
 *
 *****************************************************************************/

#ifndef hypre_SSTRUCT_MATMULT_HEADER
#define hypre_SSTRUCT_MATMULT_HEADER

/*--------------------------------------------------------------------------
 * SStructPMatmult data structure
 *--------------------------------------------------------------------------*/

typedef struct hypre_SStructPMatmultData_struct
{
   hypre_StructMatmultData    *smmdata;      /* struct matmult data object */
   HYPRE_Int                ***smmid;        /* (nvars x nvars) array of matmult id-arrays */
   HYPRE_Int                 **smmsz;        /* (nvars x nvars) array of matmult id-array sizes */
   HYPRE_Int                   nvars;

   HYPRE_Int                   nmatrices;
   hypre_SStructPMatrix      **pmatrices;  /* matrices we are multiplying */
   HYPRE_Int                   nterms;
   HYPRE_Int                  *terms;
   HYPRE_Int                  *transposes;

   hypre_CommPkg              *comm_pkg;        /* agglomerated communication package */
   HYPRE_Complex             **comm_data;       /* agglomerated communication data */

} hypre_SStructPMatmultData;

/*--------------------------------------------------------------------------
 * SStructMatmult data structure
 *--------------------------------------------------------------------------*/

typedef struct hypre_SStructMatmultData_struct
{
   HYPRE_Int                    nparts;
   hypre_SStructPMatmultData  **pmmdata;   /* pointer to nparts array */

   HYPRE_Int                    nmatrices;
   hypre_SStructMatrix        **matrices;  /* matrices we are multiplying */
   HYPRE_Int                    nterms;
   HYPRE_Int                   *terms;
   HYPRE_Int                   *transposes;

   hypre_CommPkg               *comm_pkg;        /* agglomerated communication package */
   HYPRE_Complex              **comm_data;       /* agglomerated communication data */

} hypre_SStructMatmultData;

#endif
/******************************************************************************
 * Copyright (c) 1998 Lawrence Livermore National Security, LLC and other
 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 ******************************************************************************/

/* sstruct_axpy.c */
HYPRE_Int hypre_SStructPAxpy ( HYPRE_Complex alpha, hypre_SStructPVector *px,
                               hypre_SStructPVector *py );
HYPRE_Int hypre_SStructPVectorPointwiseDivpy ( HYPRE_Complex alpha, hypre_SStructPVector *px,
                                               hypre_SStructPVector *pz, HYPRE_Complex beta,
                                               hypre_SStructPVector *py );
HYPRE_Int hypre_SStructAxpy ( HYPRE_Complex alpha, hypre_SStructVector *x, hypre_SStructVector *y );
HYPRE_Int hypre_SStructVectorPointwiseDivpy ( HYPRE_Complex *alpha, hypre_SStructVector *x,
                                              hypre_SStructVector *z, HYPRE_Complex *beta,
                                              hypre_SStructVector *y );

/* sstruct_copy.c */
HYPRE_Int hypre_SStructPCopy ( hypre_SStructPVector *px, hypre_SStructPVector *py );
HYPRE_Int hypre_SStructPartialPCopy ( hypre_SStructPVector *px, hypre_SStructPVector *py,
                                      hypre_BoxArrayArray **array_boxes );
HYPRE_Int hypre_SStructCopy ( hypre_SStructVector *x, hypre_SStructVector *y );

/* sstruct_graph.c */
HYPRE_Int hypre_SStructGraphRef ( hypre_SStructGraph *graph, hypre_SStructGraph **graph_ref );
HYPRE_Int hypre_SStructGraphGetUVEntryRank( hypre_SStructGraph *graph, HYPRE_Int part,
                                            HYPRE_Int var, hypre_Index index, HYPRE_BigInt *rank );
HYPRE_BigInt hypre_SStructGraphFindBoxEndpt ( hypre_SStructGraph *graph, HYPRE_Int part,
                                              HYPRE_Int var,
                                              HYPRE_Int proc, HYPRE_Int endpt, HYPRE_Int boxi );
HYPRE_Int hypre_SStructGraphFindSGridEndpts ( hypre_SStructGraph *graph, HYPRE_Int part,
                                              HYPRE_Int var, HYPRE_Int proc, HYPRE_Int endpt, HYPRE_BigInt *endpts );

/* sstruct_grid.c */
HYPRE_Int hypre_SStructVariableGetOffset ( HYPRE_SStructVariable vartype, HYPRE_Int ndim,
                                           hypre_Index varoffset );
HYPRE_Int hypre_SStructPGridCreate ( MPI_Comm comm, HYPRE_Int ndim,
                                     hypre_SStructPGrid **pgrid_ptr );
HYPRE_Int hypre_SStructPGridRef( hypre_SStructPGrid *pgrid, hypre_SStructPGrid **pgrid_ref);
HYPRE_Int hypre_SStructPGridDestroy ( hypre_SStructPGrid *pgrid );
HYPRE_Int hypre_SStructPGridSetExtents ( hypre_SStructPGrid *pgrid, hypre_Index ilower,
                                         hypre_Index iupper );
HYPRE_Int hypre_SStructPGridSetCellSGrid ( hypre_SStructPGrid *pgrid,
                                           hypre_StructGrid *cell_sgrid );
HYPRE_Int hypre_SStructPGridSetSGrid ( hypre_StructGrid *sgrid, hypre_SStructPGrid *pgrid,
                                       HYPRE_Int var );
HYPRE_Int hypre_SStructPGridSetVariables ( hypre_SStructPGrid *pgrid, HYPRE_Int nvars,
                                           HYPRE_SStructVariable *vartypes );
HYPRE_Int hypre_SStructPGridSetPNeighbor ( hypre_SStructPGrid *pgrid, hypre_Box *pneighbor_box,
                                           hypre_Index pnbor_offset );
HYPRE_Int hypre_SStructPGridAssemble ( hypre_SStructPGrid *pgrid );
HYPRE_Int hypre_SStructPGridGetMaxBoxSize ( hypre_SStructPGrid *pgrid );
HYPRE_Int hypre_SStructGridRef ( hypre_SStructGrid *grid, hypre_SStructGrid **grid_ref );
HYPRE_Int hypre_SStructGridComputeGlobalSizes ( hypre_SStructGrid  *grid );
HYPRE_Int hypre_SStructGridAssembleBoxManagers ( hypre_SStructGrid *grid );
HYPRE_Int hypre_SStructGridAssembleNborBoxManagers ( hypre_SStructGrid *grid );
HYPRE_Int hypre_SStructGridCreateCommInfo ( hypre_SStructGrid *grid );
HYPRE_Int hypre_SStructGridFindBoxManEntry ( hypre_SStructGrid *grid, HYPRE_Int part,
                                             hypre_Index index, HYPRE_Int var, hypre_BoxManEntry **entry_ptr );
HYPRE_Int hypre_SStructGridFindNborBoxManEntry ( hypre_SStructGrid *grid, HYPRE_Int part,
                                                 hypre_Index index, HYPRE_Int var, hypre_BoxManEntry **entry_ptr );
HYPRE_Int hypre_SStructGridBoxProcFindBoxManEntry ( hypre_SStructGrid *grid, HYPRE_Int part,
                                                    HYPRE_Int var, HYPRE_Int box, HYPRE_Int proc, hypre_BoxManEntry **entry_ptr );
HYPRE_Int hypre_SStructBoxManEntryGetCSRstrides ( hypre_BoxManEntry *entry, hypre_Index strides );
HYPRE_Int hypre_SStructBoxManEntryGetGhstrides ( hypre_BoxManEntry *entry, hypre_Index strides );
HYPRE_Int hypre_SStructBoxManEntryGetGlobalCSRank ( hypre_BoxManEntry *entry, hypre_Index index,
                                                    HYPRE_BigInt *rank_ptr );
HYPRE_Int hypre_SStructBoxManEntryGetGlobalGhrank ( hypre_BoxManEntry *entry, hypre_Index index,
                                                    HYPRE_BigInt *rank_ptr );
HYPRE_Int hypre_SStructBoxManEntryGetProcess ( hypre_BoxManEntry *entry, HYPRE_Int *proc_ptr );
HYPRE_Int hypre_SStructBoxManEntryGetBoxnum ( hypre_BoxManEntry *entry, HYPRE_Int *id_ptr );
HYPRE_Int hypre_SStructBoxManEntryGetPart ( hypre_BoxManEntry *entry, HYPRE_Int part,
                                            HYPRE_Int *part_ptr );
HYPRE_Int hypre_SStructIndexToNborIndex( hypre_Index index, hypre_Index root, hypre_Index nbor_root,
                                         hypre_Index coord, hypre_Index dir, HYPRE_Int ndim, hypre_Index nbor_index );
HYPRE_Int hypre_SStructBoxToNborBox ( hypre_Box *box, hypre_Index root, hypre_Index nbor_root,
                                      hypre_Index coord, hypre_Index dir );
HYPRE_Int hypre_SStructNborIndexToIndex( hypre_Index nbor_index, hypre_Index root,
                                         hypre_Index nbor_root, hypre_Index coord, hypre_Index dir, HYPRE_Int ndim, hypre_Index index );
HYPRE_Int hypre_SStructNborBoxToBox ( hypre_Box *nbor_box, hypre_Index root, hypre_Index nbor_root,
                                      hypre_Index coord, hypre_Index dir );
HYPRE_Int hypre_SStructVarToNborVar ( hypre_SStructGrid *grid, HYPRE_Int part, HYPRE_Int var,
                                      HYPRE_Int *coord, HYPRE_Int *nbor_var_ptr );
HYPRE_Int hypre_SStructGridSetNumGhost ( hypre_SStructGrid *grid, HYPRE_Int *num_ghost );
HYPRE_Int hypre_SStructBoxManEntryGetGlobalRank ( hypre_BoxManEntry *entry, hypre_Index index,
                                                  HYPRE_BigInt *rank_ptr, HYPRE_Int type );
HYPRE_Int hypre_SStructBoxManEntryGetStrides ( hypre_BoxManEntry *entry, hypre_Index strides,
                                               HYPRE_Int type );
HYPRE_Int hypre_SStructBoxNumMap ( hypre_SStructGrid *grid, HYPRE_Int part, HYPRE_Int boxnum,
                                   HYPRE_Int **num_varboxes_ptr, HYPRE_Int ***map_ptr );
HYPRE_Int hypre_SStructCellGridBoxNumMap ( hypre_SStructGrid *grid, HYPRE_Int part,
                                           HYPRE_Int ***num_varboxes_ptr, HYPRE_Int ****map_ptr );
HYPRE_Int hypre_SStructCellBoxToVarBox ( hypre_Box *box, hypre_Index offset, hypre_Index varoffset,
                                         HYPRE_Int *valid );
HYPRE_Int hypre_SStructGridIntersect ( hypre_SStructGrid *grid, HYPRE_Int part, HYPRE_Int var,
                                       hypre_Box *box, HYPRE_Int action, hypre_BoxManEntry ***entries_ptr, HYPRE_Int *nentries_ptr );
HYPRE_Int hypre_SStructGridPrintGLVis ( hypre_SStructGrid *grid, const char *meshprefix,
                                        HYPRE_Real *trans, HYPRE_Real *origin );
HYPRE_Int hypre_SStructGridCoarsen ( hypre_SStructGrid *fgrid, hypre_IndexRef origin,
                                     hypre_Index *strides, hypre_Index *periodic, hypre_SStructGrid **cgrid_ptr );
HYPRE_Int hypre_SStructGridSetActiveParts ( hypre_SStructGrid *grid, HYPRE_Int *active );
HYPRE_Int hypre_SStructGridSetAllPartsActive ( hypre_SStructGrid *grid );
HYPRE_Int hypre_SStructGridGetMaxBoxSize ( hypre_SStructGrid *grid );
HYPRE_Int hypre_SStructGridPrint ( FILE *file, hypre_SStructGrid *grid );
HYPRE_Int hypre_SStructGridRead ( MPI_Comm comm, FILE *file, hypre_SStructGrid **grid_ptr );

/* sstruct_innerprod.c */
HYPRE_Int hypre_SStructPInnerProd ( hypre_SStructPVector *px, hypre_SStructPVector *py,
                                    HYPRE_Real *presult_ptr );
HYPRE_Int hypre_SStructPInnerProdLocal ( hypre_SStructPVector *px, hypre_SStructPVector *py,
                                         HYPRE_Real *presult_ptr );
HYPRE_Int hypre_SStructInnerProd ( hypre_SStructVector *x, hypre_SStructVector *y,
                                   HYPRE_Real *result_ptr );

/* sstruct_matrix.c */
HYPRE_Int hypre_SStructPMatrixRef ( hypre_SStructPMatrix *matrix,
                                    hypre_SStructPMatrix **matrix_ref );
HYPRE_Int hypre_SStructPMatrixCreate ( MPI_Comm comm, hypre_SStructPGrid *pgrid,
                                       hypre_SStructStencil **stencils, hypre_SStructPMatrix **pmatrix_ptr );
HYPRE_Int hypre_SStructPMatrixDestroy ( hypre_SStructPMatrix *pmatrix );
HYPRE_Int hypre_SStructPMatrixInitialize ( hypre_SStructPMatrix *pmatrix );
HYPRE_Int hypre_SStructPMatrixSetValues ( hypre_SStructPMatrix *pmatrix, hypre_Index index,
                                          HYPRE_Int var, HYPRE_Int nentries, HYPRE_Int *entries, HYPRE_Complex *values, HYPRE_Int action );
HYPRE_Int hypre_SStructPMatrixSetBoxValues( hypre_SStructPMatrix *pmatrix, hypre_Box *set_box,
                                            HYPRE_Int var, HYPRE_Int nentries, HYPRE_Int *entries, hypre_Box *value_box, HYPRE_Complex *values,
                                            HYPRE_Int action );
HYPRE_Int hypre_SStructPMatrixAccumulate ( hypre_SStructPMatrix *pmatrix );
HYPRE_Int hypre_SStructPMatrixAssemble ( hypre_SStructPMatrix *pmatrix );
HYPRE_Int hypre_SStructPMatrixSetTranspose( hypre_SStructPMatrix *pmatrix, HYPRE_Int transpose,
                                            HYPRE_Int *resize );
HYPRE_Int hypre_SStructPMatrixSetSymmetric ( hypre_SStructPMatrix *pmatrix, HYPRE_Int var,
                                             HYPRE_Int to_var, HYPRE_Int symmetric );
HYPRE_Int hypre_SStructPMatrixSetCEntries( hypre_SStructPMatrix *pmatrix, HYPRE_Int var,
                                           HYPRE_Int to_var, HYPRE_Int num_centries, HYPRE_Int *centries );
HYPRE_Int hypre_SStructPMatrixSetDomainStride ( hypre_SStructPMatrix *pmatrix,
                                                hypre_Index dom_stride );
HYPRE_Int hypre_SStructPMatrixSetRangeStride ( hypre_SStructPMatrix *pmatrix,
                                               hypre_Index ran_stride );
HYPRE_Int hypre_SStructPMatrixPrint ( const char *filename, hypre_SStructPMatrix *pmatrix,
                                      HYPRE_Int all );
HYPRE_Int hypre_SStructPMatrixGetDiagonal ( hypre_SStructPMatrix *pmatrix,
                                            hypre_SStructPVector *pdiag );
HYPRE_Int hypre_SStructUMatrixInitialize ( hypre_SStructMatrix *matrix,
                                           HYPRE_MemoryLocation  memory_location );
HYPRE_Int hypre_SStructUMatrixSetValues ( hypre_SStructMatrix *matrix, HYPRE_Int part,
                                          hypre_Index index, HYPRE_Int var, HYPRE_Int nentries, HYPRE_Int *entries, HYPRE_Complex *values,
                                          HYPRE_Int action );
HYPRE_Int hypre_SStructUMatrixSetBoxValuesHelper( hypre_SStructMatrix *matrix, HYPRE_Int part,
                                                  hypre_Box *set_box, HYPRE_Int var, HYPRE_Int nentries, HYPRE_Int *entries, hypre_Box *value_box,
                                                  HYPRE_Complex *values, HYPRE_Int action, HYPRE_IJMatrix ijmatrix );
HYPRE_Int hypre_SStructUMatrixSetBoxValues( hypre_SStructMatrix *matrix, HYPRE_Int part,
                                            hypre_Box *set_box, HYPRE_Int var, HYPRE_Int nentries, HYPRE_Int *entries, hypre_Box *value_box,
                                            HYPRE_Complex *values, HYPRE_Int action );
HYPRE_Int hypre_SStructUMatrixAssemble ( hypre_SStructMatrix *matrix );
HYPRE_Int hypre_SStructMatrixMapDataBox ( hypre_SStructMatrix  *matrix, HYPRE_Int part,
                                          HYPRE_Int vi, HYPRE_Int  vj, hypre_Box *map_vbox );
HYPRE_Int hypre_SStructMatrixRef ( hypre_SStructMatrix *matrix, hypre_SStructMatrix **matrix_ref );
HYPRE_Int hypre_SStructMatrixSplitEntries ( hypre_SStructMatrix *matrix, HYPRE_Int part,
                                            HYPRE_Int var, HYPRE_Int nentries, HYPRE_Int *entries, HYPRE_Int *nSentries_ptr,
                                            HYPRE_Int **Sentries_ptr, HYPRE_Int *nUentries_ptr, HYPRE_Int **Uentries_ptr );
HYPRE_Int hypre_SStructMatrixSetValues ( HYPRE_SStructMatrix matrix, HYPRE_Int part,
                                         HYPRE_Int *index, HYPRE_Int var, HYPRE_Int nentries, HYPRE_Int *entries, HYPRE_Complex *values,
                                         HYPRE_Int action );
HYPRE_Int hypre_SStructMatrixSetBoxValues( HYPRE_SStructMatrix  matrix, HYPRE_Int part,
                                           hypre_Box *set_box, HYPRE_Int var, HYPRE_Int nentries, HYPRE_Int *entries, hypre_Box *value_box,
                                           HYPRE_Complex *values, HYPRE_Int action );
HYPRE_Int hypre_SStructMatrixSetInterPartValues( HYPRE_SStructMatrix  matrix, HYPRE_Int part,
                                                 hypre_Box *set_box, HYPRE_Int var, HYPRE_Int nentries, HYPRE_Int *entries, hypre_Box *value_box,
                                                 HYPRE_Complex *values, HYPRE_Int action );
HYPRE_Int hypre_SStructMatrixCompressUToS( HYPRE_SStructMatrix matrix, HYPRE_Int action );
HYPRE_Int hypre_SStructMatrixBoxesToUMatrix( hypre_SStructMatrix *A, hypre_SStructGrid *grid,
                                             hypre_IJMatrix **ij_Ahat_ptr, hypre_BoxArray ***convert_boxa);
hypre_IJMatrix* hypre_SStructMatrixToUMatrix( HYPRE_SStructMatrix  matrix,
                                              HYPRE_Int fill_diagonal );
HYPRE_Int hypre_SStructMatrixHaloToUMatrix ( hypre_SStructMatrix *A, hypre_SStructGrid *grid,
                                             hypre_IJMatrix **ij_Ahat_ptr, HYPRE_Int halo_size );
HYPRE_Int hypre_SStructMatrixGetDiagonal ( hypre_SStructMatrix *matrix,
                                           hypre_SStructVector **diag_ptr );
HYPRE_MemoryLocation hypre_SStructMatrixMemoryLocation(hypre_SStructMatrix *matrix);

/* sstruct_matvec.c */
HYPRE_Int hypre_SStructPMatvecCreate ( void **pmatvec_vdata_ptr );
HYPRE_Int hypre_SStructPMatvecSetTranspose ( void *pmatvec_vdata, HYPRE_Int  transpose );
HYPRE_Int hypre_SStructPMatvecSetup ( void *pmatvec_vdata, hypre_SStructPMatrix *pA,
                                      hypre_SStructPVector *px );
HYPRE_Int hypre_SStructPMatvecCompute ( void *pmatvec_vdata, HYPRE_Complex alpha,
                                        hypre_SStructPMatrix *pA, hypre_SStructPVector *px, HYPRE_Complex beta, hypre_SStructPVector *pb,
                                        hypre_SStructPVector *py );
HYPRE_Int hypre_SStructPMatvecDestroy ( void *pmatvec_vdata );
HYPRE_Int hypre_SStructPMatvec ( HYPRE_Complex alpha, hypre_SStructPMatrix *pA,
                                 hypre_SStructPVector *px, HYPRE_Complex beta, hypre_SStructPVector *py );
HYPRE_Int hypre_SStructMatvecCreate ( void **matvec_vdata_ptr );
HYPRE_Int hypre_SStructMatvecSetTranspose ( void *matvec_vdata, HYPRE_Int  transpose );
HYPRE_Int hypre_SStructMatvecSetup ( void *matvec_vdata, hypre_SStructMatrix *A,
                                     hypre_SStructVector *x );
HYPRE_Int hypre_SStructMatvecCompute ( void *matvec_vdata, HYPRE_Complex alpha,
                                       hypre_SStructMatrix *A, hypre_SStructVector *x, HYPRE_Complex beta, hypre_SStructVector *b,
                                       hypre_SStructVector *y );
HYPRE_Int hypre_SStructMatvecDestroy ( void *matvec_vdata );
HYPRE_Int hypre_SStructMatvec ( HYPRE_Complex alpha, hypre_SStructMatrix *A, hypre_SStructVector *x,
                                HYPRE_Complex beta, hypre_SStructVector *y );

/* sstruct_matmult.c */
HYPRE_Int
hypre_SStructPMatmultCreate(HYPRE_Int                   nmatrices_input,
                            hypre_SStructPMatrix      **pmatrices_input,
                            HYPRE_Int                   nterms,
                            HYPRE_Int                  *terms_input,
                            HYPRE_Int                  *trans_input,
                            hypre_SStructPMatmultData **pmmdata_ptr);
HYPRE_Int
hypre_SStructPMatmultDestroy( hypre_SStructPMatmultData *pmmdata );
HYPRE_Int
hypre_SStructPMatmultInitialize( hypre_SStructPMatmultData  *pmmdata,
                                 HYPRE_Int                   assemble_grid,
                                 hypre_SStructPMatrix      **pM_ptr );
HYPRE_Int
hypre_SStructPMatmultCommSetup( hypre_SStructPMatmultData *pmmdata );
HYPRE_Int
hypre_SStructPMatmultCommunicate( hypre_SStructPMatmultData *pmmdata );
HYPRE_Int
hypre_SStructPMatmultCompute( hypre_SStructPMatmultData *pmmdata,
                              hypre_SStructPMatrix      *pM );
HYPRE_Int
hypre_SStructPMatmult(HYPRE_Int               nmatrices,
                      hypre_SStructPMatrix  **matrices,
                      HYPRE_Int               nterms,
                      HYPRE_Int              *terms,
                      HYPRE_Int              *trans,
                      hypre_SStructPMatrix  **M_ptr );
HYPRE_Int
hypre_SStructPMatmat( hypre_SStructPMatrix  *A,
                      hypre_SStructPMatrix  *B,
                      hypre_SStructPMatrix **M_ptr );
HYPRE_Int
hypre_SStructPMatrixPtAP( hypre_SStructPMatrix  *A,
                          hypre_SStructPMatrix  *P,
                          hypre_SStructPMatrix **M_ptr );
HYPRE_Int
hypre_SStructPMatrixRAP( hypre_SStructPMatrix  *R,
                         hypre_SStructPMatrix  *A,
                         hypre_SStructPMatrix  *P,
                         hypre_SStructPMatrix **M_ptr );
HYPRE_Int
hypre_SStructPMatrixRTtAP( hypre_SStructPMatrix  *RT,
                           hypre_SStructPMatrix  *A,
                           hypre_SStructPMatrix  *P,
                           hypre_SStructPMatrix **M_ptr );
HYPRE_Int
hypre_SStructMatmultCreate(HYPRE_Int                  nmatrices_input,
                           hypre_SStructMatrix      **matrices_input,
                           HYPRE_Int                  nterms,
                           HYPRE_Int                 *terms_input,
                           HYPRE_Int                 *trans_input,
                           hypre_SStructMatmultData **mmdata_ptr);
HYPRE_Int
hypre_SStructMatmultDestroy( hypre_SStructMatmultData *mmdata );
HYPRE_Int
hypre_SStructMatmultInitialize( hypre_SStructMatmultData   *mmdata,
                                hypre_SStructMatrix       **M_ptr );
HYPRE_Int
hypre_SStructMatmultCommunicate( hypre_SStructMatmultData *mmdata );
HYPRE_Int
hypre_SStructMatmultComputeS( hypre_SStructMatmultData *mmdata,
                              hypre_SStructMatrix      *M );
HYPRE_Int
hypre_SStructMatmultComputeU( hypre_SStructMatmultData *mmdata,
                              hypre_SStructMatrix      *M );
HYPRE_Int
hypre_SStructMatmultCompute( hypre_SStructMatmultData *mmdata,
                             hypre_SStructMatrix      *M );
HYPRE_Int
hypre_SStructMatmult(HYPRE_Int             nmatrices,
                     hypre_SStructMatrix **matrices,
                     HYPRE_Int             nterms,
                     HYPRE_Int            *terms,
                     HYPRE_Int            *trans,
                     hypre_SStructMatrix **M_ptr );
HYPRE_Int
hypre_SStructMatmat( hypre_SStructMatrix  *A,
                     hypre_SStructMatrix  *B,
                     hypre_SStructMatrix **M_ptr );
HYPRE_Int
hypre_SStructMatrixPtAP( hypre_SStructMatrix  *A,
                         hypre_SStructMatrix  *P,
                         hypre_SStructMatrix **M_ptr );
HYPRE_Int
hypre_SStructMatrixRAP( hypre_SStructMatrix  *R,
                        hypre_SStructMatrix  *A,
                        hypre_SStructMatrix  *P,
                        hypre_SStructMatrix **M_ptr );
HYPRE_Int
hypre_SStructMatrixRTtAP( hypre_SStructMatrix  *RT,
                          hypre_SStructMatrix  *A,
                          hypre_SStructMatrix  *P,
                          hypre_SStructMatrix **M_ptr );

/* sstruct_matop.c */
HYPRE_Int hypre_SStructPMatrixComputeRowSum ( hypre_SStructPMatrix *pA, HYPRE_Int type,
                                              hypre_SStructPVector *prowsum );
HYPRE_Int hypre_SStructMatrixComputeRowSum ( hypre_SStructMatrix *A, HYPRE_Int type,
                                             hypre_SStructVector **rowsum_ptr );
HYPRE_Int hypre_SStructMatrixComputeL1Norms ( hypre_SStructMatrix *A, HYPRE_Int option,
                                              hypre_SStructVector **l1_norms_ptr );

/* sstruct_scale.c */
HYPRE_Int hypre_SStructPScale ( HYPRE_Complex alpha, hypre_SStructPVector *py );
HYPRE_Int hypre_SStructScale ( HYPRE_Complex alpha, hypre_SStructVector *y );

/* sstruct_stencil.c */
HYPRE_Int hypre_SStructStencilRef ( hypre_SStructStencil *stencil,
                                    hypre_SStructStencil **stencil_ref );

/* sstruct_vector.c */
HYPRE_Int hypre_SStructPVectorRef ( hypre_SStructPVector *vector,
                                    hypre_SStructPVector **vector_ref );
HYPRE_Int hypre_SStructPVectorCreate ( MPI_Comm comm, hypre_SStructPGrid *pgrid,
                                       hypre_SStructPVector **pvector_ptr );
HYPRE_Int hypre_SStructPVectorDestroy ( hypre_SStructPVector *pvector );
HYPRE_Int hypre_SStructPVectorInitialize ( hypre_SStructPVector *pvector );
HYPRE_Int hypre_SStructPVectorSetValues ( hypre_SStructPVector *pvector, hypre_Index index,
                                          HYPRE_Int var, HYPRE_Complex *value, HYPRE_Int action );
HYPRE_Int hypre_SStructPVectorSetBoxValues( hypre_SStructPVector *pvector, hypre_Box *set_box,
                                            HYPRE_Int var, hypre_Box *value_box, HYPRE_Complex *values, HYPRE_Int action );
HYPRE_Int hypre_SStructPVectorAccumulate ( hypre_SStructPVector *pvector );
HYPRE_Int hypre_SStructPVectorAssemble ( hypre_SStructPVector *pvector );
HYPRE_Int hypre_SStructPVectorGather ( hypre_SStructPVector *pvector );
HYPRE_Int hypre_SStructPVectorGetValues ( hypre_SStructPVector *pvector, hypre_Index index,
                                          HYPRE_Int var, HYPRE_Complex *value );
HYPRE_Int hypre_SStructPVectorGetBoxValues( hypre_SStructPVector *pvector, hypre_Box *set_box,
                                            HYPRE_Int var, hypre_Box *value_box, HYPRE_Complex *values );
HYPRE_Int hypre_SStructPVectorSetConstantValues ( hypre_SStructPVector *pvector,
                                                  HYPRE_Complex value );
HYPRE_Int hypre_SStructPVectorSetRandomValues ( hypre_SStructPVector *pvector, HYPRE_Int seed );
HYPRE_Int hypre_SStructPVectorPrint ( const char *filename, hypre_SStructPVector *pvector,
                                      HYPRE_Int all );
HYPRE_Int hypre_SStructVectorRef ( hypre_SStructVector *vector, hypre_SStructVector **vector_ref );
HYPRE_Int hypre_SStructVectorSetConstantValues ( hypre_SStructVector *vector, HYPRE_Complex value );
HYPRE_Int hypre_SStructVectorSetRandomValues ( hypre_SStructVector *vector, HYPRE_Int seed );
HYPRE_Int hypre_SStructVectorConvert ( hypre_SStructVector *vector,
                                       hypre_ParVector **parvector_ptr );
HYPRE_Int hypre_SStructVectorParConvert ( hypre_SStructVector *vector,
                                          hypre_ParVector **parvector_ptr );
HYPRE_Int hypre_SStructVectorRestore ( hypre_SStructVector *vector, hypre_ParVector *parvector );
HYPRE_Int hypre_SStructVectorParRestore ( hypre_SStructVector *vector, hypre_ParVector *parvector );
HYPRE_Int hypre_SStructPVectorInitializeShell ( hypre_SStructPVector *pvector );
HYPRE_Int hypre_SStructVectorInitializeShell ( hypre_SStructVector *vector );
HYPRE_Int hypre_SStructVectorClearGhostValues ( hypre_SStructVector *vector );
HYPRE_Int hypre_SStructVectorPrintGLVis ( hypre_SStructVector *vector, const char *fileprefix );
HYPRE_MemoryLocation hypre_SStructVectorMemoryLocation(hypre_SStructVector *vector);
HYPRE_Int hypre_SStructVectorPointwiseDivision ( hypre_SStructVector *x, hypre_SStructVector *y,
                                                 hypre_SStructVector **z_ptr );
HYPRE_Int hypre_SStructVectorPointwiseProduct ( hypre_SStructVector *x, hypre_SStructVector *y,
                                                hypre_SStructVector **z_ptr );
HYPRE_Int hypre_SStructVectorPointwiseInverse ( hypre_SStructVector *x,
                                                hypre_SStructVector **y_ptr );

#ifdef __cplusplus
}
#endif

#ifdef HYPRE_MIXED_PRECISION
/* The following is for user compiles and the order is important.  The first
 * header ensures that we do not change prototype names in user files or in the
 * second header file.  The second header contains all the prototypes needed by
 * users for mixed precision. */
#ifndef hypre_MP_BUILD
#include "_hypre_sstruct_mv_mup_undef.h"
#include "_hypre_sstruct_mv_mup.h"
#endif
#endif

#endif

