| 150 | /*************** SpgmrSolve ******************************************/ |
| 151 | |
| 152 | int SpgmrSolve(SpgmrMem mem, void *A_data, N_Vector x, N_Vector b, |
| 153 | int pretype, int gstype, real delta, int max_restarts, |
| 154 | void *P_data, N_Vector sx, N_Vector sb, ATimesFn atimes, |
| 155 | PSolveFn psolve, real *res_norm, int *nli, int *nps) |
| 156 | { |
| 157 | N_Vector *V, xcor, vtemp; |
| 158 | real **Hes, *givens, *yg; |
| 159 | real s_r0_norm, beta, rotation_product, r_norm, s_product, rho; |
| 160 | boole preOnLeft, preOnRight, scale_x, scale_b, converged; |
| 161 | int i, j, k, l, l_plus_1, l_max, krydim, ier, ntries; |
| 162 | |
| 163 | if (mem == NULL) return(SPGMR_MEM_NULL); |
| 164 | |
| 165 | /* Make local copies of mem variables */ |
| 166 | l_max = mem->l_max; |
| 167 | V = mem->V; |
| 168 | Hes = mem->Hes; |
| 169 | givens = mem->givens; |
| 170 | xcor = mem->xcor; |
| 171 | yg = mem->yg; |
| 172 | vtemp = mem->vtemp; |
| 173 | |
| 174 | *nli = *nps = 0; /* Initialize counters */ |
| 175 | converged = FALSE; /* Initialize converged flag */ |
| 176 | |
| 177 | if (max_restarts < 0) max_restarts = 0; |
| 178 | |
| 179 | if ((pretype != LEFT) && (pretype != RIGHT) && (pretype != BOTH)) |
| 180 | pretype = NONE; |
| 181 | |
| 182 | preOnLeft = ((pretype == LEFT) || (pretype == BOTH)); |
| 183 | preOnRight = ((pretype == RIGHT) || (pretype == BOTH)); |
| 184 | scale_x = (sx != NULL); |
| 185 | scale_b = (sb != NULL); |
| 186 | |
| 187 | /* Set vtemp and V[0] to initial (unscaled) residual r_0 = b - A*x_0 */ |
| 188 | |
| 189 | if (N_VDotProd(x, x) == ZERO) { |
| 190 | N_VScale(ONE, b, vtemp); |
| 191 | } else { |
| 192 | if (atimes(A_data, x, vtemp) != 0) |
| 193 | return(SPGMR_ATIMES_FAIL); |
| 194 | N_VLinearSum(ONE, b, -ONE, vtemp, vtemp); |
| 195 | } |
| 196 | N_VScale(ONE, vtemp, V[0]); |
| 197 | |
| 198 | /* Apply b-scaling to vtemp, get L2 norm of sb r_0, and return if small */ |
| 199 | /* |
| 200 | if (scale_b) N_VProd(sb, vtemp, vtemp); |
| 201 | s_r0_norm = RSqrt(N_VDotProd(vtemp, vtemp)); |
| 202 | if (s_r0_norm <= delta) return(SPGMR_SUCCESS); |
| 203 | */ |
| 204 | /* Apply left preconditioner and b-scaling to V[0] = r_0 */ |
| 205 | |
| 206 | if (preOnLeft) { |
| 207 | ier = psolve(P_data, V[0], vtemp, LEFT); |
| 208 | (*nps)++; |
| 209 | if (ier != 0) |
no test coverage detected