00001 /* 00002 * ----------------------------------------------------------------- 00003 * $Revision: 1.2 $ 00004 * $Date: 2006/11/29 00:05:07 $ 00005 * ----------------------------------------------------------------- 00006 * Programmer(s): Aaron Collier @ LLNL 00007 * ----------------------------------------------------------------- 00008 * Copyright (c) 2005, The Regents of the University of California. 00009 * Produced at the Lawrence Livermore National Laboratory. 00010 * All rights reserved. 00011 * For details, see the LICENSE file. 00012 * ----------------------------------------------------------------- 00013 * This is the header file for the implementation of the scaled 00014 * preconditioned Transpose-Free Quasi-Minimal Residual (SPTFQMR) 00015 * linear solver. 00016 * 00017 * The SPTFQMR algorithm solves a linear system of the form Ax = b. 00018 * Preconditioning is allowed on the left (PREC_LEFT), right 00019 * (PREC_RIGHT), or both (PREC_BOTH). Scaling is allowed on both 00020 * sides. We denote the preconditioner and scaling matrices as 00021 * follows: 00022 * P1 = left preconditioner 00023 * P2 = right preconditioner 00024 * S1 = diagonal matrix of scale factors for P1-inverse b 00025 * S2 = diagonal matrix of scale factors for P2 x 00026 * The matrices A, P1, and P2 are not required explicitly; only 00027 * routines that provide A, P1-inverse, and P2-inverse as operators 00028 * are required. 00029 * 00030 * In this notation, SPTFQMR applies the underlying TFQMR method to 00031 * the equivalent transformed system: 00032 * Abar xbar = bbar, where 00033 * Abar = S1 (P1-inverse) A (P2-inverse) (S2-inverse), 00034 * bbar = S1 (P1-inverse) b, and 00035 * xbar = S2 P2 x. 00036 * 00037 * The scaling matrices must be chosen so that vectors 00038 * S1 P1-inverse b and S2 P2 x have dimensionless components. If 00039 * preconditioning is done on the left only (P2 = I), by a matrix P, 00040 * then S2 must be a scaling for x, while S1 is a scaling for 00041 * P-inverse b, and so may also be taken as a scaling for x. 00042 * Similarly, if preconditioning is done on the right only (P1 = I, 00043 * P2 = P), then S1 must be a scaling for b, while S2 is a scaling 00044 * for P x, and may also be taken as a scaling for b. 00045 * 00046 * The stopping test for the SPTFQMR 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 SPTFQMR 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) to solve P1 x = y or P2 x = y for x, 00056 * given y. 00057 * The three user calls are: 00058 * mem = SptfqmrMalloc(lmax, vec_tmpl); 00059 * to initialize memory 00060 * flag = SptfqmrSolve(mem, A_data, x, b, pretype, delta, P_data, 00061 * sx, sb, atimes, psolve, res_norm, nli, nps); 00062 * to solve the system, and 00063 * SptfqmrFree(mem); 00064 * to free the memory allocated by SptfqmrMalloc(). 00065 * Complete details for specifying atimes() and psolve() and for the 00066 * usage calls are given in the paragraphs below and in the header 00067 * file sundials_iterative.h. 00068 * ----------------------------------------------------------------- 00069 */ 00070 00071 #ifndef _SPTFQMR_H 00072 #define _SPTFQMR_H 00073 00074 #ifdef __cplusplus /* wrapper to enable C++ usage */ 00075 extern "C" { 00076 #endif 00077 00078 #include <sundials/sundials_iterative.h> 00079 00080 /* 00081 * ----------------------------------------------------------------- 00082 * Types: struct SptfqmrMemRec and struct *SptfqmrMem 00083 * ----------------------------------------------------------------- 00084 * A variable declaration of type struct *SptfqmrMem denotes a pointer 00085 * to a data structure of type struct SptfqmrMemRec. The SptfqmrMemRec 00086 * structure contains numerous fields that must be accessed by the 00087 * SPTFQMR linear solver module. 00088 * 00089 * l_max maximum Krylov subspace dimension that SptfqmrSolve will 00090 * be permitted to use 00091 * 00092 * r_star vector (type N_Vector) which holds the initial scaled, 00093 * preconditioned linear system residual 00094 * 00095 * q/d/v/p/u/r vectors (type N_Vector) used for workspace by 00096 * the SPTFQMR algorithm 00097 * 00098 * vtemp1/vtemp2/vtemp3 scratch vectors (type N_Vector) used as 00099 * temporary storage 00100 * ----------------------------------------------------------------- 00101 */ 00102 00103 typedef struct { 00104 00105 int l_max; 00106 00107 N_Vector r_star; 00108 N_Vector q; 00109 N_Vector d; 00110 N_Vector v; 00111 N_Vector p; 00112 N_Vector *r; 00113 N_Vector u; 00114 N_Vector vtemp1; 00115 N_Vector vtemp2; 00116 N_Vector vtemp3; 00117 00118 } SptfqmrMemRec, *SptfqmrMem; 00119 00120 /* 00121 * ----------------------------------------------------------------- 00122 * Function : SptfqmrMalloc 00123 * ----------------------------------------------------------------- 00124 * SptfqmrMalloc allocates additional memory needed by the SPTFQMR 00125 * linear solver module. 00126 * 00127 * l_max maximum Krylov subspace dimension that SptfqmrSolve will 00128 * be permitted to use 00129 * 00130 * vec_tmpl implementation-specific template vector (type N_Vector) 00131 * (created using either N_VNew_Serial or N_VNew_Parallel) 00132 * 00133 * If successful, SptfqmrMalloc returns a non-NULL memory pointer. If 00134 * an error occurs, then a NULL pointer is returned. 00135 * ----------------------------------------------------------------- 00136 */ 00137 00138 SUNDIALS_EXPORT SptfqmrMem SptfqmrMalloc(int l_max, N_Vector vec_tmpl); 00139 00140 /* 00141 * ----------------------------------------------------------------- 00142 * Function : SptfqmrSolve 00143 * ----------------------------------------------------------------- 00144 * SptfqmrSolve solves the linear system Ax = b by means of a scaled 00145 * preconditioned Transpose-Free Quasi-Minimal Residual (SPTFQMR) 00146 * method. 00147 * 00148 * mem pointer to an internal memory block allocated during a 00149 * prior call to SptfqmrMalloc 00150 * 00151 * A_data pointer to a data structure containing information 00152 * about the coefficient matrix A (passed to user-supplied 00153 * function referenced by atimes (function pointer)) 00154 * 00155 * x vector (type N_Vector) containing initial guess x_0 upon 00156 * entry, but which upon return contains an approximate solution 00157 * of the linear system Ax = b (solution only valid if return 00158 * value is either SPTFQMR_SUCCESS or SPTFQMR_RES_REDUCED) 00159 * 00160 * b vector (type N_Vector) set to the right-hand side vector b 00161 * of the linear system (undisturbed by function) 00162 * 00163 * pretype variable (type int) indicating the type of 00164 * preconditioning to be used (see sundials_iterative.h) 00165 * 00166 * delta tolerance on the L2 norm of the scaled, preconditioned 00167 * residual (if return value == SPTFQMR_SUCCESS, then 00168 * ||sb*P1_inv*(b-Ax)||_L2 <= delta) 00169 * 00170 * P_data pointer to a data structure containing preconditioner 00171 * information (passed to user-supplied function referenced 00172 * by psolve (function pointer)) 00173 * 00174 * sx vector (type N_Vector) containing positive scaling factors 00175 * for x (pass sx == NULL if scaling NOT required) 00176 * 00177 * sb vector (type N_Vector) containing positive scaling factors 00178 * for b (pass sb == NULL if scaling NOT required) 00179 * 00180 * atimes user-supplied routine responsible for computing the 00181 * matrix-vector product Ax (see sundials_iterative.h) 00182 * 00183 * psolve user-supplied routine responsible for solving the 00184 * preconditioned linear system Pz = r (ignored if 00185 * pretype == PREC_NONE) (see sundials_iterative.h) 00186 * 00187 * res_norm pointer (type realtype*) to the L2 norm of the 00188 * scaled, preconditioned residual (if return value 00189 * is either SPTFQMR_SUCCESS or SPTFQMR_RES_REDUCED, then 00190 * *res_norm = ||sb*P1_inv*(b-Ax)||_L2, where x is 00191 * the computed approximate solution, sb is the diagonal 00192 * scaling matrix for the right-hand side b, and P1_inv 00193 * is the inverse of the left-preconditioner matrix) 00194 * 00195 * nli pointer (type int*) to the total number of linear 00196 * iterations performed 00197 * 00198 * nps pointer (type int*) to the total number of calls made 00199 * to the psolve routine 00200 * ----------------------------------------------------------------- 00201 */ 00202 00203 SUNDIALS_EXPORT int SptfqmrSolve(SptfqmrMem mem, void *A_data, N_Vector x, N_Vector b, 00204 int pretype, realtype delta, void *P_data, N_Vector sx, 00205 N_Vector sb, ATimesFn atimes, PSolveFn psolve, 00206 realtype *res_norm, int *nli, int *nps); 00207 00208 /* Return values for SptfqmrSolve */ 00209 00210 #define SPTFQMR_SUCCESS 0 /* SPTFQMR algorithm converged */ 00211 #define SPTFQMR_RES_REDUCED 1 /* SPTFQMR did NOT converge, but the 00212 residual was reduced */ 00213 #define SPTFQMR_CONV_FAIL 2 /* SPTFQMR algorithm failed to converge */ 00214 #define SPTFQMR_PSOLVE_FAIL_REC 3 /* psolve failed recoverably */ 00215 #define SPTFQMR_ATIMES_FAIL_REC 4 /* atimes failed recoverably */ 00216 #define SPTFQMR_PSET_FAIL_REC 5 /* pset faild recoverably */ 00217 00218 #define SPTFQMR_MEM_NULL -1 /* mem argument is NULL */ 00219 #define SPTFQMR_ATIMES_FAIL_UNREC -2 /* atimes returned failure flag */ 00220 #define SPTFQMR_PSOLVE_FAIL_UNREC -3 /* psolve failed unrecoverably */ 00221 #define SPTFQMR_PSET_FAIL_UNREC -4 /* pset failed unrecoverably */ 00222 00223 /* 00224 * ----------------------------------------------------------------- 00225 * Function : SptfqmrFree 00226 * ----------------------------------------------------------------- 00227 * SptfqmrFree frees the memory allocated by a call to SptfqmrMalloc. 00228 * It is illegal to use the pointer mem after a call to SptfqmrFree. 00229 * ----------------------------------------------------------------- 00230 */ 00231 00232 SUNDIALS_EXPORT void SptfqmrFree(SptfqmrMem mem); 00233 00234 /* 00235 * ----------------------------------------------------------------- 00236 * Macro : SPTFQMR_VTEMP 00237 * ----------------------------------------------------------------- 00238 * This macro provides access to the work vector vtemp1 in the 00239 * memory block of the SPTFQMR module. The argument mem is the 00240 * memory pointer returned by SptfqmrMalloc, of type SptfqmrMem, 00241 * and the macro value is of type N_Vector. 00242 * 00243 * Note: Only used by IDA (vtemp1 contains P_inverse F if 00244 * nli_inc == 0). 00245 * ----------------------------------------------------------------- 00246 */ 00247 00248 #define SPTFQMR_VTEMP(mem) (mem->vtemp1) 00249 00250 #ifdef __cplusplus 00251 } 00252 #endif 00253 00254 #endif