/*BHEADER********************************************************************** * Copyright (c) 2008, Lawrence Livermore National Security, LLC. * Produced at the Lawrence Livermore National Laboratory. * This file is part of HYPRE. See file COPYRIGHT for details. * * HYPRE is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License (as published by the Free * Software Foundation) version 2.1 dated February 1999. * * $Revision: 2.4 $ ***********************************************************************EHEADER*/ #ifndef HYPRE_SSTRUCT_MV_HEADER #define HYPRE_SSTRUCT_MV_HEADER #include "HYPRE_utilities.h" #include "HYPRE.h" #include "HYPRE_struct_mv.h" #include "HYPRE_IJ_mv.h" #ifdef __cplusplus extern "C" { #endif /*-------------------------------------------------------------------------- *--------------------------------------------------------------------------*/ /** * @name SStruct System Interface * * This interface represents a semi-structured-grid conceptual view of a linear * system. * * @memo A semi-structured-grid conceptual interface **/ /*@{*/ /*-------------------------------------------------------------------------- *--------------------------------------------------------------------------*/ /** * @name SStruct Grids **/ /*@{*/ struct hypre_SStructGrid_struct; /** * A grid object is constructed out of several structured ``parts'' and an * optional unstructured ``part''. Each structured part has its own abstract * index space. **/ typedef struct hypre_SStructGrid_struct *HYPRE_SStructGrid; enum hypre_SStructVariable_enum { HYPRE_SSTRUCT_VARIABLE_UNDEFINED = -1, HYPRE_SSTRUCT_VARIABLE_CELL = 0, HYPRE_SSTRUCT_VARIABLE_NODE = 1, HYPRE_SSTRUCT_VARIABLE_XFACE = 2, HYPRE_SSTRUCT_VARIABLE_YFACE = 3, HYPRE_SSTRUCT_VARIABLE_ZFACE = 4, HYPRE_SSTRUCT_VARIABLE_XEDGE = 5, HYPRE_SSTRUCT_VARIABLE_YEDGE = 6, HYPRE_SSTRUCT_VARIABLE_ZEDGE = 7 }; /** * An enumerated type that supports cell centered, node centered, face centered, * and edge centered variables. Face centered variables are split into x-face, * y-face, and z-face variables, and edge centered variables are split into * x-edge, y-edge, and z-edge variables. The edge centered variable types are * only used in 3D. In 2D, edge centered variables are handled by the face * centered types. * * Variables are referenced relative to an abstract (cell centered) index in the * following way: * \begin{itemize} * \item cell centered variables are aligned with the index; * \item node centered variables are aligned with the cell corner * at relative index (1/2, 1/2, 1/2); * \item x-face, y-face, and z-face centered variables are aligned * with the faces at relative indexes (1/2, 0, 0), (0, 1/2, 0), * and (0, 0, 1/2), respectively; * \item x-edge, y-edge, and z-edge centered variables are aligned * with the edges at relative indexes (0, 1/2, 1/2), (1/2, 0, 1/2), * and (1/2, 1/2, 0), respectively. * \end{itemize} * * The supported identifiers are: * \begin{itemize} * \item {\tt HYPRE\_SSTRUCT\_VARIABLE\_CELL} * \item {\tt HYPRE\_SSTRUCT\_VARIABLE\_NODE} * \item {\tt HYPRE\_SSTRUCT\_VARIABLE\_XFACE} * \item {\tt HYPRE\_SSTRUCT\_VARIABLE\_YFACE} * \item {\tt HYPRE\_SSTRUCT\_VARIABLE\_ZFACE} * \item {\tt HYPRE\_SSTRUCT\_VARIABLE\_XEDGE} * \item {\tt HYPRE\_SSTRUCT\_VARIABLE\_YEDGE} * \item {\tt HYPRE\_SSTRUCT\_VARIABLE\_ZEDGE} * \end{itemize} * * NOTE: Although variables are referenced relative to a unique abstract * cell-centered index, some variables are associated with multiple grid cells. * For example, node centered variables in 3D are associated with 8 cells (away * from boundaries). Although grid cells are distributed uniquely to different * processes, variables may be owned by multiple processes because they may be * associated with multiple cells. **/ typedef enum hypre_SStructVariable_enum HYPRE_SStructVariable; /** * Create an {\tt ndim}-dimensional grid object with {\tt nparts} structured * parts. **/ int HYPRE_SStructGridCreate(MPI_Comm comm, int ndim, int nparts, HYPRE_SStructGrid *grid); /** * Destroy a grid object. An object should be explicitly destroyed using this * destructor when the user's code no longer needs direct access to it. Once * destroyed, the object must not be referenced again. Note that the object may * not be deallocated at the completion of this call, since there may be * internal package references to the object. The object will then be destroyed * when all internal reference counts go to zero. **/ int HYPRE_SStructGridDestroy(HYPRE_SStructGrid grid); /** * Set the extents for a box on a structured part of the grid. **/ int HYPRE_SStructGridSetExtents(HYPRE_SStructGrid grid, int part, int *ilower, int *iupper); /** * Describe the variables that live on a structured part of the grid. **/ int HYPRE_SStructGridSetVariables(HYPRE_SStructGrid grid, int part, int nvars, HYPRE_SStructVariable *vartypes); /** * Describe additional variables that live at a particular index. These * variables are appended to the array of variables set in * \Ref{HYPRE_SStructGridSetVariables}, and are referenced as such. **/ int HYPRE_SStructGridAddVariables(HYPRE_SStructGrid grid, int part, int *index, int nvars, HYPRE_SStructVariable *vartypes); /** * Describe how regions just outside of a part relate to other parts. This is * done a box at a time. * * The indexes {\tt ilower} and {\tt iupper} map directly to the indexes {\tt * nbor\_ilower} and {\tt nbor\_iupper}. Although, it is required that indexes * increase from {\tt ilower} to {\tt iupper}, indexes may increase and/or * decrease from {\tt nbor\_ilower} to {\tt nbor\_iupper}. * * The {\tt index\_map} describes the mapping of indexes 0, 1, and 2 on part * {\tt part} to the corresponding indexes on part {\tt nbor\_part}. For * example, triple (1, 2, 0) means that indexes 0, 1, and 2 on part {\tt part} * map to indexes 1, 2, and 0 on part {\tt nbor\_part}, respectively. * * NOTE: All parts related to each other via this routine must have an identical * list of variables and variable types. For example, if part 0 has only two * variables on it, a cell centered variable and a node centered variable, and * we declare part 1 to be a neighbor of part 0, then part 1 must also have only * two variables on it, and they must be of type cell and node. **/ int HYPRE_SStructGridSetNeighborBox(HYPRE_SStructGrid grid, int part, int *ilower, int *iupper, int nbor_part, int *nbor_ilower, int *nbor_iupper, int *index_map); /* * ** TEMPORARY routine until more thorough testing is completed ** * * This is the same as HYPRE_SStructGridSetNeighborBox, except for the addition * of the last argument which enables hypre to couple a part to itself. * * SetNeighborBox calls can imply that certain variables on the grid are the * same as other variables on the grid. This redundancy must be reconciled * somehow. When SetNeighborBox couples the index spaces of two different * parts, hypre can resolve this redundancy issue very easily. However, when * SetNeighborBox couples the index space of a part to itself, resolving the * redundancey is much more complex and costly in general. The best solution to * this problem is to let the user dictate which variables are primary variables * and which are secondary variables. * * The last argument 'primary' works as follows: * * 'primary' > 0 - the 'part' box variables are primary variables * 'primary' = 0 - the 'part' box variables are secondary variables * 'primary' < 0 - let hypre decide; only works for two different parts * **/ int HYPRE_SStructGridSetNeighborBoxZ(HYPRE_SStructGrid grid, int part, int *ilower, int *iupper, int nbor_part, int *nbor_ilower, int *nbor_iupper, int *index_map, int primary); /** * Add an unstructured part to the grid. The variables in the unstructured part * of the grid are referenced by a global rank between 0 and the total number of * unstructured variables minus one. Each process owns some unique consecutive * range of variables, defined by {\tt ilower} and {\tt iupper}. * * NOTE: This is just a placeholder. This part of the interface is not finished. **/ int HYPRE_SStructGridAddUnstructuredPart(HYPRE_SStructGrid grid, int ilower, int iupper); /** * Finalize the construction of the grid before using. **/ int HYPRE_SStructGridAssemble(HYPRE_SStructGrid grid); /** * Set periodic for a particular part. **/ int HYPRE_SStructGridSetPeriodic(HYPRE_SStructGrid grid, int part, int *periodic); /** * Setting ghost in the sgrids. **/ int HYPRE_SStructGridSetNumGhost(HYPRE_SStructGrid grid, int *num_ghost); /*@}*/ /*-------------------------------------------------------------------------- *--------------------------------------------------------------------------*/ /** * @name SStruct Stencils **/ /*@{*/ struct hypre_SStructStencil_struct; /** * The stencil object. **/ typedef struct hypre_SStructStencil_struct *HYPRE_SStructStencil; /** * Create a stencil object for the specified number of spatial dimensions and * stencil entries. **/ int HYPRE_SStructStencilCreate(int ndim, int size, HYPRE_SStructStencil *stencil); /** * Destroy a stencil object. **/ int HYPRE_SStructStencilDestroy(HYPRE_SStructStencil stencil); /** * Set a stencil entry. **/ int HYPRE_SStructStencilSetEntry(HYPRE_SStructStencil stencil, int entry, int *offset, int var); /*@}*/ /*-------------------------------------------------------------------------- *--------------------------------------------------------------------------*/ /** * @name SStruct Graphs **/ /*@{*/ struct hypre_SStructGraph_struct; /** * The graph object is used to describe the nonzero structure of a matrix. **/ typedef struct hypre_SStructGraph_struct *HYPRE_SStructGraph; /** * Create a graph object. **/ int HYPRE_SStructGraphCreate(MPI_Comm comm, HYPRE_SStructGrid grid, HYPRE_SStructGraph *graph); /** * Destroy a graph object. **/ int HYPRE_SStructGraphDestroy(HYPRE_SStructGraph graph); /** * Set the stencil for a variable on a structured part of the grid. **/ int HYPRE_SStructGraphSetStencil(HYPRE_SStructGraph graph, int part, int var, HYPRE_SStructStencil stencil); /** * Add a non-stencil graph entry at a particular index. This graph entry is * appended to the existing graph entries, and is referenced as such. * * NOTE: Users are required to set graph entries on all processes that own the * associated variables. This means that some data will be multiply defined. **/ int HYPRE_SStructGraphAddEntries(HYPRE_SStructGraph graph, int part, int *index, int var, int to_part, int *to_index, int to_var); /** * Set the storage type of the associated matrix object. It is used before * AddEntries and Assemble to compute the right ranks in the graph. * * NOTE: This routine is only necessary for implementation reasons, and will * eventually be removed. * * @see HYPRE_SStructMatrixSetObjectType **/ int HYPRE_SStructGraphSetObjectType(HYPRE_SStructGraph graph, int type); /** * Finalize the construction of the graph before using. **/ int HYPRE_SStructGraphAssemble(HYPRE_SStructGraph graph); /*@}*/ /*-------------------------------------------------------------------------- *--------------------------------------------------------------------------*/ /** * @name SStruct Matrices **/ /*@{*/ struct hypre_SStructMatrix_struct; /** * The matrix object. **/ typedef struct hypre_SStructMatrix_struct *HYPRE_SStructMatrix; /** * Create a matrix object. **/ int HYPRE_SStructMatrixCreate(MPI_Comm comm, HYPRE_SStructGraph graph, HYPRE_SStructMatrix *matrix); /** * Destroy a matrix object. **/ int HYPRE_SStructMatrixDestroy(HYPRE_SStructMatrix matrix); /** * Prepare a matrix object for setting coefficient values. **/ int HYPRE_SStructMatrixInitialize(HYPRE_SStructMatrix matrix); /** * Set matrix coefficients index by index. The {\tt values} array is of length * {\tt nentries}. * * NOTE: For better efficiency, use \Ref{HYPRE_SStructMatrixSetBoxValues} to set * coefficients a box at a time. * * NOTE: Users are required to set values on all processes that own the * associated variables. This means that some data will be multiply defined. * * NOTE: The entries in this routine must all be of the same type: either * stencil or non-stencil, but not both. Also, if they are stencil entries, * they must all represent couplings to the same variable type (there are no * such restrictions for non-stencil entries). * * If the matrix is complex, then {\tt values} consists of pairs of doubles * representing the real and imaginary parts of each complex value. * * @see HYPRE_SStructMatrixSetComplex **/ int HYPRE_SStructMatrixSetValues(HYPRE_SStructMatrix matrix, int part, int *index, int var, int nentries, int *entries, double *values); /** * Add to matrix coefficients index by index. The {\tt values} array is of * length {\tt nentries}. * * NOTE: For better efficiency, use \Ref{HYPRE_SStructMatrixAddToBoxValues} to * set coefficients a box at a time. * * NOTE: Users are required to set values on all processes that own the * associated variables. This means that some data will be multiply defined. * * NOTE: The entries in this routine must all be of the same type: either * stencil or non-stencil, but not both. Also, if they are stencil entries, * they must all represent couplings to the same variable type. * * If the matrix is complex, then {\tt values} consists of pairs of doubles * representing the real and imaginary parts of each complex value. * * @see HYPRE_SStructMatrixSetComplex **/ int HYPRE_SStructMatrixAddToValues(HYPRE_SStructMatrix matrix, int part, int *index, int var, int nentries, int *entries, double *values); /** * Set matrix coefficients a box at a time. The data in {\tt values} is ordered * as follows: * \begin{verbatim} m = 0; for (k = ilower[2]; k <= iupper[2]; k++) for (j = ilower[1]; j <= iupper[1]; j++) for (i = ilower[0]; i <= iupper[0]; i++) for (entry = 0; entry < nentries; entry++) { values[m] = ...; m++; } \end{verbatim} * * NOTE: Users are required to set values on all processes that own the * associated variables. This means that some data will be multiply defined. * * NOTE: The entries in this routine must all be of the same type: either * stencil or non-stencil, but not both. Also, if they are stencil entries, * they must all represent couplings to the same variable type (there are no * such restrictions for non-stencil entries). * * If the matrix is complex, then {\tt values} consists of pairs of doubles * representing the real and imaginary parts of each complex value. * * @see HYPRE_SStructMatrixSetComplex **/ int HYPRE_SStructMatrixSetBoxValues(HYPRE_SStructMatrix matrix, int part, int *ilower, int *iupper, int var, int nentries, int *entries, double *values); /** * Add to matrix coefficients a box at a time. The data in {\tt values} is * ordered as in \Ref{HYPRE_SStructMatrixSetBoxValues}. * * NOTE: Users are required to set values on all processes that own the * associated variables. This means that some data will be multiply defined. * * NOTE: The entries in this routine must all be of stencil type. Also, they * must all represent couplings to the same variable type. * * If the matrix is complex, then {\tt values} consists of pairs of doubles * representing the real and imaginary parts of each complex value. * * @see HYPRE_SStructMatrixSetComplex **/ int HYPRE_SStructMatrixAddToBoxValues(HYPRE_SStructMatrix matrix, int part, int *ilower, int *iupper, int var, int nentries, int *entries, double *values); /** * Finalize the construction of the matrix before using. **/ int HYPRE_SStructMatrixAssemble(HYPRE_SStructMatrix matrix); /** * Define symmetry properties for the stencil entries in the matrix. The * boolean argument {\tt symmetric} is applied to stencil entries on part {\tt * part} that couple variable {\tt var} to variable {\tt to\_var}. A value of * -1 may be used for {\tt part}, {\tt var}, or {\tt to\_var} to specify * ``all''. For example, if {\tt part} and {\tt to\_var} are set to -1, then * the boolean is applied to stencil entries on all parts that couple variable * {\tt var} to all other variables. * * By default, matrices are assumed to be nonsymmetric. Significant * storage savings can be made if the matrix is symmetric. **/ int HYPRE_SStructMatrixSetSymmetric(HYPRE_SStructMatrix matrix, int part, int var, int to_var, int symmetric); /** * Define symmetry properties for all non-stencil matrix entries. **/ int HYPRE_SStructMatrixSetNSSymmetric(HYPRE_SStructMatrix matrix, int symmetric); /** * Set the storage type of the matrix object to be constructed. Currently, {\tt * type} can be either {\tt HYPRE\_SSTRUCT} (the default), {\tt HYPRE\_STRUCT}, * or {\tt HYPRE\_PARCSR}. * * @see HYPRE_SStructMatrixGetObject **/ int HYPRE_SStructMatrixSetObjectType(HYPRE_SStructMatrix matrix, int type); /** * Get a reference to the constructed matrix object. * * @see HYPRE_SStructMatrixSetObjectType **/ int HYPRE_SStructMatrixGetObject(HYPRE_SStructMatrix matrix, void **object); /** * Set the matrix to be complex. **/ int HYPRE_SStructMatrixSetComplex(HYPRE_SStructMatrix matrix); /** * Print the matrix to file. This is mainly for debugging purposes. **/ int HYPRE_SStructMatrixPrint(const char *filename, HYPRE_SStructMatrix matrix, int all); /*@}*/ /*-------------------------------------------------------------------------- *--------------------------------------------------------------------------*/ /** * @name SStruct Vectors **/ /*@{*/ struct hypre_SStructVector_struct; /** * The vector object. **/ typedef struct hypre_SStructVector_struct *HYPRE_SStructVector; /** * Create a vector object. **/ int HYPRE_SStructVectorCreate(MPI_Comm comm, HYPRE_SStructGrid grid, HYPRE_SStructVector *vector); /** * Destroy a vector object. **/ int HYPRE_SStructVectorDestroy(HYPRE_SStructVector vector); /** * Prepare a vector object for setting coefficient values. **/ int HYPRE_SStructVectorInitialize(HYPRE_SStructVector vector); /** * Set vector coefficients index by index. * * NOTE: For better efficiency, use \Ref{HYPRE_SStructVectorSetBoxValues} to set * coefficients a box at a time. * * NOTE: Users are required to set values on all processes that own the * associated variables. This means that some data will be multiply defined. * * If the vector is complex, then {\tt value} consists of a pair of doubles * representing the real and imaginary parts of the complex value. * * @see HYPRE_SStructVectorSetComplex **/ int HYPRE_SStructVectorSetValues(HYPRE_SStructVector vector, int part, int *index, int var, double *value); /** * Add to vector coefficients index by index. * * NOTE: For better efficiency, use \Ref{HYPRE_SStructVectorAddToBoxValues} to * set coefficients a box at a time. * * NOTE: Users are required to set values on all processes that own the * associated variables. This means that some data will be multiply defined. * * If the vector is complex, then {\tt value} consists of a pair of doubles * representing the real and imaginary parts of the complex value. * * @see HYPRE_SStructVectorSetComplex **/ int HYPRE_SStructVectorAddToValues(HYPRE_SStructVector vector, int part, int *index, int var, double *value); /** * Set vector coefficients a box at a time. The data in {\tt values} is ordered * as follows: * \begin{verbatim} m = 0; for (k = ilower[2]; k <= iupper[2]; k++) for (j = ilower[1]; j <= iupper[1]; j++) for (i = ilower[0]; i <= iupper[0]; i++) { values[m] = ...; m++; } \end{verbatim} * * NOTE: Users are required to set values on all processes that own the * associated variables. This means that some data will be multiply defined. * * If the vector is complex, then {\tt values} consists of pairs of doubles * representing the real and imaginary parts of each complex value. * * @see HYPRE_SStructVectorSetComplex **/ int HYPRE_SStructVectorSetBoxValues(HYPRE_SStructVector vector, int part, int *ilower, int *iupper, int var, double *values); /** * Add to vector coefficients a box at a time. The data in {\tt values} is * ordered as in \Ref{HYPRE_SStructVectorSetBoxValues}. * * NOTE: Users are required to set values on all processes that own the * associated variables. This means that some data will be multiply defined. * * If the vector is complex, then {\tt values} consists of pairs of doubles * representing the real and imaginary parts of each complex value. * * @see HYPRE_SStructVectorSetComplex **/ int HYPRE_SStructVectorAddToBoxValues(HYPRE_SStructVector vector, int part, int *ilower, int *iupper, int var, double *values); /** * Finalize the construction of the vector before using. **/ int HYPRE_SStructVectorAssemble(HYPRE_SStructVector vector); /** * Gather vector data so that efficient {\tt GetValues} can be done. This * routine must be called prior to calling {\tt GetValues} to insure that * correct and consistent values are returned, especially for non cell-centered * data that is shared between more than one processor. **/ int HYPRE_SStructVectorGather(HYPRE_SStructVector vector); /** * Get vector coefficients index by index. * * NOTE: For better efficiency, use \Ref{HYPRE_SStructVectorGetBoxValues} to get * coefficients a box at a time. * * NOTE: Users may only get values on processes that own the associated * variables. * * If the vector is complex, then {\tt value} consists of a pair of doubles * representing the real and imaginary parts of the complex value. * * @see HYPRE_SStructVectorSetComplex **/ int HYPRE_SStructVectorGetValues(HYPRE_SStructVector vector, int part, int *index, int var, double *value); /** * Get vector coefficients a box at a time. The data in {\tt values} is ordered * as in \Ref{HYPRE_SStructVectorSetBoxValues}. * * NOTE: Users may only get values on processes that own the associated * variables. * * If the vector is complex, then {\tt values} consists of pairs of doubles * representing the real and imaginary parts of each complex value. * * @see HYPRE_SStructVectorSetComplex **/ int HYPRE_SStructVectorGetBoxValues(HYPRE_SStructVector vector, int part, int *ilower, int *iupper, int var, double *values); /** * Set the storage type of the vector object to be constructed. Currently, {\tt * type} can be either {\tt HYPRE\_SSTRUCT} (the default), {\tt HYPRE\_STRUCT}, * or {\tt HYPRE\_PARCSR}. * * @see HYPRE_SStructVectorGetObject **/ int HYPRE_SStructVectorSetObjectType(HYPRE_SStructVector vector, int type); /** * Get a reference to the constructed vector object. * * @see HYPRE_SStructVectorSetObjectType **/ int HYPRE_SStructVectorGetObject(HYPRE_SStructVector vector, void **object); /** * Set the vector to be complex. **/ int HYPRE_SStructVectorSetComplex(HYPRE_SStructVector vector); /** * Print the vector to file. This is mainly for debugging purposes. **/ int HYPRE_SStructVectorPrint(const char *filename, HYPRE_SStructVector vector, int all); /*@}*/ /*@}*/ /*-------------------------------------------------------------------------- *--------------------------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif