sundials_spgmr.h

Go to the documentation of this file.
00001 /*
00002  * -----------------------------------------------------------------
00003  * $Revision: 1.2 $
00004  * $Date: 2006/11/29 00:05:07 $
00005  * ----------------------------------------------------------------- 
00006  * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh and
00007  *                Radu Serban @ LLNL
00008  * -----------------------------------------------------------------
00009  * Copyright (c) 2002, The Regents of the University of California.
00010  * Produced at the Lawrence Livermore National Laboratory.
00011  * All rights reserved.
00012  * For details, see the LICENSE file.
00013  * -----------------------------------------------------------------
00014  * This is the header file for the implementation of SPGMR Krylov
00015  * iterative linear solver.  The SPGMR algorithm is based on the
00016  * Scaled Preconditioned GMRES (Generalized Minimal Residual)
00017  * method.
00018  *
00019  * The SPGMR algorithm solves a linear system A x = b.
00020  * Preconditioning is allowed on the left, right, or both.
00021  * Scaling is allowed on both sides, and restarts are also allowed.
00022  * We denote the preconditioner and scaling matrices as follows:
00023  *   P1 = left preconditioner
00024  *   P2 = right preconditioner
00025  *   S1 = diagonal matrix of scale factors for P1-inverse b
00026  *   S2 = diagonal matrix of scale factors for P2 x
00027  * The matrices A, P1, and P2 are not required explicitly; only
00028  * routines that provide A, P1-inverse, and P2-inverse as
00029  * operators are required.
00030  *
00031  * In this notation, SPGMR applies the underlying GMRES method to
00032  * the equivalent transformed system
00033  *   Abar xbar = bbar , where
00034  *   Abar = S1 (P1-inverse) A (P2-inverse) (S2-inverse) ,
00035  *   bbar = S1 (P1-inverse) b , and   xbar = S2 P2 x .
00036  *
00037  * The scaling matrices must be chosen so that vectors S1
00038  * P1-inverse b and S2 P2 x have dimensionless components.
00039  * If preconditioning is done on the left only (P2 = I), by a
00040  * matrix P, then S2 must be a scaling for x, while S1 is a
00041  * scaling for P-inverse b, and so may also be taken as a scaling
00042  * for x.  Similarly, if preconditioning is done on the right only
00043  * (P1 = I, P2 = P), then S1 must be a scaling for b, while S2 is
00044  * a scaling for P x, and may also be taken as a scaling for b.
00045  *
00046  * The stopping test for the SPGMR iterations is on the L2 norm of
00047  * the scaled preconditioned residual:
00048  *      || bbar - Abar xbar ||_2  <  delta
00049  * with an input test constant delta.
00050  *
00051  * The usage of this SPGMR solver involves supplying two routines
00052  * and making three calls.  The user-supplied routines are
00053  *    atimes (A_data, x, y) to compute y = A x, given x,
00054  * and
00055  *    psolve (P_data, x, y, lr)
00056  *                to solve P1 x = y or P2 x = y for x, given y.
00057  * The three user calls are:
00058  *    mem  = SpgmrMalloc(lmax, vec_tmpl);
00059  *           to initialize memory,
00060  *    flag = SpgmrSolve(mem,A_data,x,b,...,
00061  *                      P_data,s1,s2,atimes,psolve,...);
00062  *           to solve the system, and
00063  *    SpgmrFree(mem);
00064  *           to free the memory created by SpgmrMalloc.
00065  * Complete details for specifying atimes and psolve and for the
00066  * usage calls are given in the paragraphs below and in iterative.h.
00067  * -----------------------------------------------------------------
00068  */
00069 
00070 #ifndef _SPGMR_H
00071 #define _SPGMR_H
00072 
00073 #ifdef __cplusplus  /* wrapper to enable C++ usage */
00074 extern "C" {
00075 #endif
00076 
00077 #include <sundials/sundials_iterative.h>
00078 
00079 /*
00080  * -----------------------------------------------------------------
00081  * Types: SpgmrMemRec, SpgmrMem
00082  * -----------------------------------------------------------------
00083  * SpgmrMem is a pointer to an SpgmrMemRec which contains
00084  * the memory needed by SpgmrSolve. The SpgmrMalloc routine
00085  * returns a pointer of type SpgmrMem which should then be passed
00086  * in subsequent calls to SpgmrSolve. The SpgmrFree routine frees
00087  * the memory allocated by SpgmrMalloc.
00088  *
00089  * l_max is the maximum Krylov dimension that SpgmrSolve will be
00090  * permitted to use.
00091  *
00092  * V is the array of Krylov basis vectors v_1, ..., v_(l_max+1),
00093  * stored in V[0], ..., V[l_max], where l_max is the second
00094  * parameter to SpgmrMalloc. Each v_i is a vector of type
00095  * N_Vector.
00096  *
00097  * Hes is the (l_max+1) x l_max Hessenberg matrix. It is stored
00098  * row-wise so that the (i,j)th element is given by Hes[i][j].
00099  *
00100  * givens is a length 2*l_max array which represents the
00101  * Givens rotation matrices that arise in the algorithm. The
00102  * Givens rotation matrices F_0, F_1, ..., F_j, where F_i is
00103  *
00104  *             1
00105  *               1
00106  *                 c_i  -s_i      <--- row i
00107  *                 s_i   c_i
00108  *                           1
00109  *                             1
00110  *
00111  * are represented in the givens vector as
00112  * givens[0]=c_0, givens[1]=s_0, givens[2]=c_1, givens[3]=s_1,
00113  * ..., givens[2j]=c_j, givens[2j+1]=s_j.
00114  *
00115  * xcor is a vector (type N_Vector) which holds the scaled,
00116  * preconditioned correction to the initial guess.
00117  *
00118  * yg is a length (l_max+1) array of realtype used to hold "short"
00119  * vectors (e.g. y and g).
00120  *
00121  * vtemp is a vector (type N_Vector) used as temporary vector
00122  * storage during calculations.
00123  * -----------------------------------------------------------------
00124  */
00125   
00126 typedef struct _SpgmrMemRec {
00127 
00128   int l_max;
00129 
00130   N_Vector *V;
00131   realtype **Hes;
00132   realtype *givens;
00133   N_Vector xcor;
00134   realtype *yg;
00135   N_Vector vtemp;
00136 
00137 } SpgmrMemRec, *SpgmrMem;
00138 
00139 /*
00140  * -----------------------------------------------------------------
00141  * Function : SpgmrMalloc
00142  * -----------------------------------------------------------------
00143  * SpgmrMalloc allocates the memory used by SpgmrSolve. It
00144  * returns a pointer of type SpgmrMem which the user of the
00145  * SPGMR package should pass to SpgmrSolve. The parameter l_max
00146  * is the maximum Krylov dimension that SpgmrSolve will be
00147  * permitted to use. The parameter vec_tmpl is a pointer to an
00148  * N_Vector used as a template to create new vectors by duplication.
00149  * This routine returns NULL if there is a memory request failure.
00150  * -----------------------------------------------------------------
00151  */
00152 
00153 SUNDIALS_EXPORT SpgmrMem SpgmrMalloc(int l_max, N_Vector vec_tmpl);
00154 
00155 /*
00156  * -----------------------------------------------------------------
00157  * Function : SpgmrSolve
00158  * -----------------------------------------------------------------
00159  * SpgmrSolve solves the linear system Ax = b using the SPGMR
00160  * method. The return values are given by the symbolic constants
00161  * below. The first SpgmrSolve parameter is a pointer to memory
00162  * allocated by a prior call to SpgmrMalloc.
00163  *
00164  * mem is the pointer returned by SpgmrMalloc to the structure
00165  * containing the memory needed by SpgmrSolve.
00166  *
00167  * A_data is a pointer to information about the coefficient
00168  * matrix A. This pointer is passed to the user-supplied function
00169  * atimes.
00170  *
00171  * x is the initial guess x_0 upon entry and the solution
00172  * N_Vector upon exit with return value SPGMR_SUCCESS or
00173  * SPGMR_RES_REDUCED. For all other return values, the output x
00174  * is undefined.
00175  *
00176  * b is the right hand side N_Vector. It is undisturbed by this
00177  * function.
00178  *
00179  * pretype is the type of preconditioning to be used. Its
00180  * legal possible values are enumerated in iterativ.h. These
00181  * values are PREC_NONE=0, PREC_LEFT=1, PREC_RIGHT=2, and
00182  * PREC_BOTH=3.
00183  *
00184  * gstype is the type of Gram-Schmidt orthogonalization to be
00185  * used. Its legal values are enumerated in iterativ.h. These
00186  * values are MODIFIED_GS=0 and CLASSICAL_GS=1.
00187  *
00188  * delta is the tolerance on the L2 norm of the scaled,
00189  * preconditioned residual. On return with value SPGMR_SUCCESS,
00190  * this residual satisfies || s1 P1_inv (b - Ax) ||_2 <= delta.
00191  *
00192  * max_restarts is the maximum number of times the algorithm is
00193  * allowed to restart.
00194  *
00195  * P_data is a pointer to preconditioner information. This
00196  * pointer is passed to the user-supplied function psolve.
00197  *
00198  * s1 is an N_Vector of positive scale factors for P1-inv b, where
00199  * P1 is the left preconditioner. (Not tested for positivity.)
00200  * Pass NULL if no scaling on P1-inv b is required.
00201  *
00202  * s2 is an N_Vector of positive scale factors for P2 x, where
00203  * P2 is the right preconditioner. (Not tested for positivity.)
00204  * Pass NULL if no scaling on P2 x is required.
00205  *
00206  * atimes is the user-supplied function which performs the
00207  * operation of multiplying A by a given vector. Its description
00208  * is given in iterative.h.
00209  *
00210  * psolve is the user-supplied function which solves a
00211  * preconditioner system Pz = r, where P is P1 or P2. Its full
00212  * description is  given in iterativ.h. The psolve function will
00213  * not be called if pretype is NONE; in that case, the user
00214  * should pass NULL for psolve.
00215  *
00216  * res_norm is a pointer to the L2 norm of the scaled,
00217  * preconditioned residual. On return with value SPGMR_SUCCESS or
00218  * SPGMR_RES_REDUCED, (*res_norm) contains the value
00219  * || s1 P1_inv (b - Ax) ||_2 for the computed solution x.
00220  * For all other return values, (*res_norm) is undefined. The
00221  * caller is responsible for allocating the memory (*res_norm)
00222  * to be filled in by SpgmrSolve.
00223  *
00224  * nli is a pointer to the number of linear iterations done in
00225  * the execution of SpgmrSolve. The caller is responsible for
00226  * allocating the memory (*nli) to be filled in by SpgmrSolve.
00227  *
00228  * nps is a pointer to the number of calls made to psolve during
00229  * the execution of SpgmrSolve. The caller is responsible for
00230  * allocating the memory (*nps) to be filled in by SpgmrSolve.
00231  *
00232  * Note: Repeated calls can be made to SpgmrSolve with varying
00233  * input arguments. If, however, the problem size N or the
00234  * maximum Krylov dimension l_max changes, then a call to
00235  * SpgmrMalloc must be made to obtain new memory for SpgmrSolve
00236  * to use.
00237  * -----------------------------------------------------------------
00238  */                                                                
00239      
00240 SUNDIALS_EXPORT int SpgmrSolve(SpgmrMem mem, void *A_data, N_Vector x, N_Vector b,
00241                    int pretype, int gstype, realtype delta, 
00242                    int max_restarts, void *P_data, N_Vector s1, 
00243                    N_Vector s2, ATimesFn atimes, PSolveFn psolve, 
00244                    realtype *res_norm, int *nli, int *nps);
00245 
00246 
00247 /* Return values for SpgmrSolve */
00248 
00249 #define SPGMR_SUCCESS            0  /* Converged                     */
00250 #define SPGMR_RES_REDUCED        1  /* Did not converge, but reduced
00251                                        norm of residual              */
00252 #define SPGMR_CONV_FAIL          2  /* Failed to converge            */
00253 #define SPGMR_QRFACT_FAIL        3  /* QRfact found singular matrix  */
00254 #define SPGMR_PSOLVE_FAIL_REC    4  /* psolve failed recoverably     */
00255 #define SPGMR_ATIMES_FAIL_REC    5  /* atimes failed recoverably     */
00256 #define SPGMR_PSET_FAIL_REC      6  /* pset faild recoverably        */
00257 
00258 #define SPGMR_MEM_NULL          -1  /* mem argument is NULL          */
00259 #define SPGMR_ATIMES_FAIL_UNREC -2  /* atimes returned failure flag  */
00260 #define SPGMR_PSOLVE_FAIL_UNREC -3  /* psolve failed unrecoverably   */
00261 #define SPGMR_GS_FAIL           -4  /* Gram-Schmidt routine faiuled  */        
00262 #define SPGMR_QRSOL_FAIL        -5  /* QRsol found singular R        */
00263 #define SPGMR_PSET_FAIL_UNREC   -6  /* pset failed unrecoverably     */
00264 
00265 /*
00266  * -----------------------------------------------------------------
00267  * Function : SpgmrFree
00268  * -----------------------------------------------------------------
00269  * SpgmrMalloc frees the memory allocated by SpgmrMalloc. It is
00270  * illegal to use the pointer mem after a call to SpgmrFree.
00271  * -----------------------------------------------------------------
00272  */                                                                
00273 
00274 SUNDIALS_EXPORT void SpgmrFree(SpgmrMem mem);
00275 
00276 /*
00277  * -----------------------------------------------------------------
00278  * Macro: SPGMR_VTEMP
00279  * -----------------------------------------------------------------
00280  * This macro provides access to the work vector vtemp in the
00281  * memory block of the SPGMR module.  The argument mem is the
00282  * memory pointer returned by SpgmrMalloc, of type SpgmrMem,
00283  * and the macro value is of type N_Vector.
00284  * On a return from SpgmrSolve with *nli = 0, this vector
00285  * contains the scaled preconditioned initial residual,
00286  * s1 * P1_inverse * (b - A x_0).
00287  * -----------------------------------------------------------------
00288  */
00289 
00290 #define SPGMR_VTEMP(mem) (mem->vtemp)
00291 
00292 #ifdef __cplusplus
00293 }
00294 #endif
00295 
00296 #endif

Generated on Fri Sep 26 07:44:17 2008 for SimTKcore by  doxygen 1.5.6