static int PSolve(realtype t, N_Vector c, N_Vector fc, N_Vector r, N_Vector z, realtype gamma, realtype delta, int lr, void *user_data) { realtype ***P; sunindextype **pivot; int jx, jy, igx, igy, iv, ig, *jigx, *jigy, mx, my, ngx; sunindextype mp; WebData wdata; wdata = (WebData) user_data; N_VScale(ONE, r, z); /* call GSIter for Gauss-Seidel iterations */ GSIter(gamma, z, wdata->vtemp, wdata); /* Do backsolves for inverse of block-diagonal preconditioner factor */ P = wdata->P; pivot = wdata->pivot; mx = wdata->mx; my = wdata->my; ngx = wdata->ngx; mp = wdata->mp; jigx = wdata->jigx; jigy = wdata->jigy; iv = 0; for (jy = 0; jy < my; jy++) { igy = jigy[jy]; for (jx = 0; jx < mx; jx++) { igx = jigx[jx]; ig = igx + igy*ngx; denseGETRS(P[ig], mp, pivot[ig], &(N_VGetArrayPointer(z)[iv])); iv += mp; } } /* Solve for the quadrature variable */ N_VGetArrayPointer(z)[NEQ] = N_VGetArrayPointer(r)[NEQ] + gamma*doubleIntgr(z,ISPEC,wdata); return(0); }
static int PSolveB(realtype t, N_Vector c, N_Vector cB, N_Vector fcB, N_Vector r, N_Vector z, realtype gamma, realtype delta, int lr, void *user_data) { realtype ***P; sunindextype **pivot; int jx, jy, igx, igy, iv, ig, *jigx, *jigy, mx, my, ngx; sunindextype mp; WebData wdata; wdata = (WebData) user_data; N_VScale(ONE, r, z); /* call GSIter for Gauss-Seidel iterations (same routine but with gamma=-gamma) */ GSIter(-gamma, z, wdata->vtemp, wdata); /* Do backsolves for inverse of block-diagonal preconditioner factor */ P = wdata->P; pivot = wdata->pivot; mx = wdata->mx; my = wdata->my; ngx = wdata->ngx; mp = wdata->mp; jigx = wdata->jigx; jigy = wdata->jigy; iv = 0; for (jy = 0; jy < my; jy++) { igy = jigy[jy]; for (jx = 0; jx < mx; jx++) { igx = jigx[jx]; ig = igx + igy*ngx; denseGETRS(P[ig], mp, pivot[ig], &(N_VGetArrayPointer(z)[iv])); iv += mp; } } return(0); }
/* This routine applies two inverse preconditioner matrices to the vector r, using the interaction-only block-diagonal Jacobian with block-grouping, denoted Jr, and Gauss-Seidel applied to the diffusion contribution to the Jacobian, denoted Jd. It first calls GSIter for a Gauss-Seidel approximation to ((I - gamma*Jd)-inverse)*r, and stores the result in z. Then it computes ((I - gamma*Jr)-inverse)*z, using LU factors of the blocks in P, and pivot information in pivot, and returns the result in z. */ static int PSolve(realtype tn, N_Vector c, N_Vector fc, N_Vector r, N_Vector z, realtype gamma, realtype delta, int lr, void *user_data, N_Vector vtemp) { realtype ***P; long int **pivot; int jx, jy, igx, igy, iv, ig, *jigx, *jigy, mx, my, ngx; long int mp; WebData wdata; wdata = (WebData) user_data; N_VScale(ONE, r, z); /* call GSIter for Gauss-Seidel iterations */ GSIter(gamma, z, vtemp, wdata); /* Do backsolves for inverse of block-diagonal preconditioner factor */ P = wdata->P; pivot = wdata->pivot; mx = wdata->mx; my = wdata->my; ngx = wdata->ngx; mp = wdata->mp; jigx = wdata->jigx; jigy = wdata->jigy; iv = 0; for (jy = 0; jy < my; jy++) { igy = jigy[jy]; for (jx = 0; jx < mx; jx++) { igx = jigx[jx]; ig = igx + igy*ngx; denseGETRS(P[ig], mp, pivot[ig], &(NV_DATA_S(z)[iv])); iv += mp; } } return(0); }