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