1 /* -----------------------------------------------------------------
2  * Programmer(s): Daniel Reynolds @ SMU
3  *                David Gardner, Carol Woodward,
4  *                Slaven Peles, Cody Balos @ LLNL
5  * -----------------------------------------------------------------
6  * SUNDIALS Copyright Start
7  * Copyright (c) 2002-2021, Lawrence Livermore National Security
8  * and Southern Methodist University.
9  * All rights reserved.
10  *
11  * See the top-level LICENSE and NOTICE files for details.
12  *
13  * SPDX-License-Identifier: BSD-3-Clause
14  * SUNDIALS Copyright End
15  * -----------------------------------------------------------------
16  * This is the header file for a generic linear solver package.
17  * It defines the SUNLinearSolver structure (_generic_SUNLinearSolver)
18  * which contains the following fields:
19  *   - an implementation-dependent 'content' field which contains
20  *     any internal data required by the solver
21  *   - an 'ops' filed which contains a structure listing operations
22  *     acting on/by such solvers
23  *
24  * We consider both direct linear solvers and iterative linear solvers
25  * as available implementations of this package.  Furthermore, iterative
26  * linear solvers can either use a matrix or be matrix-free.  As a
27  * result of these different solver characteristics, some of the
28  * routines are applicable only to some types of linear solver.
29  * -----------------------------------------------------------------
30  * This header file contains:
31  *   - enumeration constants for all SUNDIALS-defined linear solver
32  *     types, as well as a generic type for user-supplied linear
33  *     solver types,
34  *   - type declarations for the _generic_SUNLinearSolver and
35  *     _generic_SUNLinearSolver_Ops structures, as well as references
36  *     to pointers to such structures (SUNLinearSolver),
37  *   - prototypes for the linear solver functions which operate
38  *     on/by SUNLinearSolver objects, and
39  *   - return codes for SUNLinearSolver objects.
40  * -----------------------------------------------------------------
41  * At a minimum, a particular implementation of a SUNLinearSolver must
42  * do the following:
43  *   - specify the 'content' field of SUNLinearSolver,
44  *   - implement the operations on/by those SUNLinearSolver objects,
45  *   - provide a constructor routine for new SUNLinearSolver objects
46  *
47  * Additionally, a SUNLinearSolver implementation may provide the
48  * following:
49  *   - "Set" routines to control solver-specific parameters/options
50  *   - "Get" routines to access solver-specific performance metrics
51  * -----------------------------------------------------------------*/
52 
53 #ifndef _SUNLINEARSOLVER_H
54 #define _SUNLINEARSOLVER_H
55 
56 #include <sundials/sundials_types.h>
57 #include <sundials/sundials_iterative.h>
58 #include <sundials/sundials_matrix.h>
59 #include <sundials/sundials_nvector.h>
60 
61 #ifdef __cplusplus  /* wrapper to enable C++ usage */
62 extern "C" {
63 #endif
64 
65 
66 /* -----------------------------------------------------------------
67  * Implemented SUNLinearSolver types and IDs:
68  * ----------------------------------------------------------------- */
69 
70 typedef enum {
71   SUNLINEARSOLVER_DIRECT,
72   SUNLINEARSOLVER_ITERATIVE,
73   SUNLINEARSOLVER_MATRIX_ITERATIVE
74 } SUNLinearSolver_Type;
75 
76 typedef enum {
77   SUNLINEARSOLVER_BAND,
78   SUNLINEARSOLVER_DENSE,
79   SUNLINEARSOLVER_KLU,
80   SUNLINEARSOLVER_LAPACKBAND,
81   SUNLINEARSOLVER_LAPACKDENSE,
82   SUNLINEARSOLVER_PCG,
83   SUNLINEARSOLVER_SPBCGS,
84   SUNLINEARSOLVER_SPFGMR,
85   SUNLINEARSOLVER_SPGMR,
86   SUNLINEARSOLVER_SPTFQMR,
87   SUNLINEARSOLVER_SUPERLUDIST,
88   SUNLINEARSOLVER_SUPERLUMT,
89   SUNLINEARSOLVER_CUSOLVERSP_BATCHQR,
90   SUNLINEARSOLVER_MAGMADENSE,
91   SUNLINEARSOLVER_CUSTOM
92 } SUNLinearSolver_ID;
93 
94 
95 /* -----------------------------------------------------------------
96  * Generic definition of SUNLinearSolver
97  * ----------------------------------------------------------------- */
98 
99 /* Forward reference for pointer to SUNLinearSolver_Ops object */
100 typedef _SUNDIALS_STRUCT_ _generic_SUNLinearSolver_Ops *SUNLinearSolver_Ops;
101 
102 /* Forward reference for pointer to SUNLinearSolver object */
103 typedef _SUNDIALS_STRUCT_ _generic_SUNLinearSolver *SUNLinearSolver;
104 
105 /* Structure containing function pointers to linear solver operations */
106 struct _generic_SUNLinearSolver_Ops {
107   SUNLinearSolver_Type (*gettype)(SUNLinearSolver);
108   SUNLinearSolver_ID   (*getid)(SUNLinearSolver);
109   int                  (*setatimes)(SUNLinearSolver, void*, ATimesFn);
110   int                  (*setpreconditioner)(SUNLinearSolver, void*,
111                                             PSetupFn, PSolveFn);
112   int                  (*setscalingvectors)(SUNLinearSolver,
113                                             N_Vector, N_Vector);
114   int                  (*initialize)(SUNLinearSolver);
115   int                  (*setup)(SUNLinearSolver, SUNMatrix);
116   int                  (*solve)(SUNLinearSolver, SUNMatrix, N_Vector,
117                                 N_Vector, realtype);
118   int                  (*numiters)(SUNLinearSolver);
119   realtype             (*resnorm)(SUNLinearSolver);
120   sunindextype         (*lastflag)(SUNLinearSolver);
121   int                  (*space)(SUNLinearSolver, long int*, long int*);
122   N_Vector             (*resid)(SUNLinearSolver);
123   int                  (*free)(SUNLinearSolver);
124 };
125 
126 /* A linear solver is a structure with an implementation-dependent
127    'content' field, and a pointer to a structure of linear solver
128    operations corresponding to that implementation. */
129 struct _generic_SUNLinearSolver {
130   void *content;
131   SUNLinearSolver_Ops ops;
132 };
133 
134 
135 /* -----------------------------------------------------------------
136  * Functions exported by SUNLinearSolver module
137  * ----------------------------------------------------------------- */
138 
139 SUNDIALS_EXPORT SUNLinearSolver SUNLinSolNewEmpty();
140 
141 SUNDIALS_EXPORT void SUNLinSolFreeEmpty(SUNLinearSolver S);
142 
143 SUNDIALS_EXPORT SUNLinearSolver_Type SUNLinSolGetType(SUNLinearSolver S);
144 
145 SUNDIALS_EXPORT SUNLinearSolver_ID SUNLinSolGetID(SUNLinearSolver S);
146 
147 SUNDIALS_EXPORT int SUNLinSolSetATimes(SUNLinearSolver S, void* A_data,
148                                        ATimesFn ATimes);
149 
150 SUNDIALS_EXPORT int SUNLinSolSetPreconditioner(SUNLinearSolver S, void* P_data,
151                                                PSetupFn Pset, PSolveFn Psol);
152 
153 SUNDIALS_EXPORT int SUNLinSolSetScalingVectors(SUNLinearSolver S, N_Vector s1,
154                                                N_Vector s2);
155 
156 SUNDIALS_EXPORT int SUNLinSolInitialize(SUNLinearSolver S);
157 
158 SUNDIALS_EXPORT int SUNLinSolSetup(SUNLinearSolver S, SUNMatrix A);
159 
160 SUNDIALS_EXPORT int SUNLinSolSolve(SUNLinearSolver S, SUNMatrix A, N_Vector x,
161                                    N_Vector b, realtype tol);
162 
163 SUNDIALS_EXPORT int SUNLinSolNumIters(SUNLinearSolver S);
164 
165 SUNDIALS_EXPORT realtype SUNLinSolResNorm(SUNLinearSolver S);
166 
167 SUNDIALS_EXPORT N_Vector SUNLinSolResid(SUNLinearSolver S);
168 
169 SUNDIALS_EXPORT sunindextype SUNLinSolLastFlag(SUNLinearSolver S);
170 
171 SUNDIALS_EXPORT int SUNLinSolSpace(SUNLinearSolver S, long int *lenrwLS,
172                                    long int *leniwLS);
173 
174 SUNDIALS_EXPORT int SUNLinSolFree(SUNLinearSolver S);
175 
176 
177 /* -----------------------------------------------------------------
178  * SUNLinearSolver return values
179  * ----------------------------------------------------------------- */
180 
181 #define SUNLS_SUCCESS               0   /* successful/converged          */
182 
183 #define SUNLS_MEM_NULL           -801   /* mem argument is NULL          */
184 #define SUNLS_ILL_INPUT          -802   /* illegal function input        */
185 #define SUNLS_MEM_FAIL           -803   /* failed memory access          */
186 #define SUNLS_ATIMES_NULL        -804   /* atimes function is NULL       */
187 #define SUNLS_ATIMES_FAIL_UNREC  -805   /* atimes unrecoverable failure  */
188 #define SUNLS_PSET_FAIL_UNREC    -806   /* pset unrecoverable failure    */
189 #define SUNLS_PSOLVE_NULL        -807   /* psolve function is NULL       */
190 #define SUNLS_PSOLVE_FAIL_UNREC  -808   /* psolve unrecoverable failure  */
191 #define SUNLS_PACKAGE_FAIL_UNREC -809   /* external package unrec. fail  */
192 #define SUNLS_GS_FAIL            -810   /* Gram-Schmidt failure          */
193 #define SUNLS_QRSOL_FAIL         -811   /* QRsol found singular R        */
194 #define SUNLS_VECTOROP_ERR       -812   /* vector operation error        */
195 
196 #define SUNLS_RES_REDUCED         801   /* nonconv. solve, resid reduced */
197 #define SUNLS_CONV_FAIL           802   /* nonconvergent solve           */
198 #define SUNLS_ATIMES_FAIL_REC     803   /* atimes failed recoverably     */
199 #define SUNLS_PSET_FAIL_REC       804   /* pset failed recoverably       */
200 #define SUNLS_PSOLVE_FAIL_REC     805   /* psolve failed recoverably     */
201 #define SUNLS_PACKAGE_FAIL_REC    806   /* external package recov. fail  */
202 #define SUNLS_QRFACT_FAIL         807   /* QRfact found singular matrix  */
203 #define SUNLS_LUFACT_FAIL         808   /* LUfact found singular matrix  */
204 
205 /* -----------------------------------------------------------------------------
206  * SUNLinearSolver messages
207  * ---------------------------------------------------------------------------*/
208 
209 #if defined(SUNDIALS_EXTENDED_PRECISION)
210 #define SUNLS_MSG_RESIDUAL "\t\tlin. iteration %ld, lin. residual: %Lg\n"
211 #elif defined(SUNDIALS_DOUBLE_PRECISION)
212 #define SUNLS_MSG_RESIDUAL "\t\tlin. iteration %ld, lin. residual: %g\n"
213 #else
214 #define SUNLS_MSG_RESIDUAL "\t\tlin. iteration %ld, lin. residual: %g\n"
215 #endif
216 
217 #ifdef __cplusplus
218 }
219 #endif
220 #endif
221