static int reslocal(long int Nlocal, realtype tt, N_Vector cc, N_Vector cp, N_Vector rr, void *res_data) { realtype *cdata, *ratesxy, *cpxy, *resxy, xx, yy, dcyli, dcyui, dcxli, dcxui; long int ix, jy, is, i, locc, ylocce, locce; UserData webdata; webdata = (UserData) res_data; /* Get data pointers, subgrid data, array sizes, work array cext. */ cdata = NV_DATA_P(cc); /* Copy local segment of cc vector into the working extended array cext. */ locc = 0; locce = nsmxsub2 + NUM_SPECIES; for (jy = 0; jy < mysub; jy++) { for (i = 0; i < nsmxsub; i++) cext[locce+i] = cdata[locc+i]; locc = locc + nsmxsub; locce = locce + nsmxsub2; } /* To facilitate homogeneous Neumann boundary conditions, when this is a boundary PE, copy data from the first interior mesh line of cc to cext. */ /* If jysub = 0, copy x-line 2 of cc to cext. */ if (jysub == 0) { for (i = 0; i < nsmxsub; i++) cext[NUM_SPECIES+i] = cdata[nsmxsub+i]; } /* If jysub = npey-1, copy x-line mysub-1 of cc to cext. */ if (jysub == npey-1) { locc = (mysub-2)*nsmxsub; locce = (mysub+1)*nsmxsub2 + NUM_SPECIES; for (i = 0; i < nsmxsub; i++) cext[locce+i] = cdata[locc+i]; } /* If ixsub = 0, copy y-line 2 of cc to cext. */ if (ixsub == 0) { for (jy = 0; jy < mysub; jy++) { locc = jy*nsmxsub + NUM_SPECIES; locce = (jy+1)*nsmxsub2; for (i = 0; i < NUM_SPECIES; i++) cext[locce+i] = cdata[locc+i]; } } /* If ixsub = npex-1, copy y-line mxsub-1 of cc to cext. */ if (ixsub == npex-1) { for (jy = 0; jy < mysub; jy++) { locc = (jy+1)*nsmxsub - 2*NUM_SPECIES; locce = (jy+2)*nsmxsub2 - NUM_SPECIES; for (i = 0; i < NUM_SPECIES; i++) cext[locce+i] = cdata[locc+i]; } } /* Loop over all grid points, setting local array rates to right-hand sides. Then set rr values appropriately for prey/predator components of F. */ for (jy = 0; jy < mysub; jy++) { ylocce = (jy+1)*nsmxsub2; yy = (jy+jysub*mysub)*dy; for (ix = 0; ix < mxsub; ix++) { locce = ylocce + (ix+1)*NUM_SPECIES; xx = (ix + ixsub*mxsub)*dx; ratesxy = IJ_Vptr(rates,ix,jy); WebRates(xx, yy, &(cext[locce]), ratesxy, webdata); resxy = IJ_Vptr(rr,ix,jy); cpxy = IJ_Vptr(cp,ix,jy); for (is = 0; is < NUM_SPECIES; is++) { dcyli = cext[locce+is] - cext[locce+is-nsmxsub2]; dcyui = cext[locce+is+nsmxsub2] - cext[locce+is]; dcxli = cext[locce+is] - cext[locce+is-NUM_SPECIES]; dcxui = cext[locce+is+NUM_SPECIES] - cext[locce+is]; rhs[is] = cox[is]*(dcxui-dcxli) + coy[is]*(dcyui-dcyli) + ratesxy[is]; if (is < np) resxy[is] = cpxy[is] - rhs[is]; else resxy[is] = - rhs[is]; } } } return(0); }
static int Precondbd(realtype tt, N_Vector cc, N_Vector cp, N_Vector rr, realtype cj, void *user_data, N_Vector tempv1, N_Vector tempv2, N_Vector tempv3) { int flag, thispe; realtype uround; realtype xx, yy, *cxy, *ewtxy, cctemp, **Pxy, *ratesxy, *Pxycol, *cpxy; realtype inc, sqru, fac, perturb_rates[NUM_SPECIES]; int is, js, ix, jy, ret; UserData webdata; void *mem; N_Vector ewt; realtype hh; webdata = (UserData)user_data; uround = UNIT_ROUNDOFF; sqru = SQRT(uround); thispe = webdata->thispe; mem = webdata->ida_mem; ewt = webdata->ewt; flag = IDAGetErrWeights(mem, ewt); check_flag(&flag, "IDAGetErrWeights", 1, thispe); flag = IDAGetCurrentStep(mem, &hh); check_flag(&flag, "IDAGetCurrentStep", 1, thispe); for (jy = 0; jy < mysub; jy++) { yy = (jy + jysub*mysub)*dy; for (ix = 0; ix < mxsub; ix++) { xx = (ix+ ixsub*mxsub)*dx; Pxy = (webdata->PP)[ix][jy]; cxy = IJ_Vptr(cc,ix,jy); cpxy = IJ_Vptr(cp,ix,jy); ewtxy= IJ_Vptr(ewt,ix,jy); ratesxy = IJ_Vptr(rates,ix,jy); for (js = 0; js < ns; js++) { inc = sqru*(MAX(ABS(cxy[js]), MAX(hh*ABS(cpxy[js]), ONE/ewtxy[js]))); cctemp = cxy[js]; /* Save the (js,ix,jy) element of cc. */ cxy[js] += inc; /* Perturb the (js,ix,jy) element of cc. */ fac = -ONE/inc; WebRates(xx, yy, cxy, perturb_rates, webdata); Pxycol = Pxy[js]; for (is = 0; is < ns; is++) Pxycol[is] = (perturb_rates[is] - ratesxy[is])*fac; if (js < np) Pxycol[js] += cj; /* Add partial with respect to cp. */ cxy[js] = cctemp; /* Restore (js,ix,jy) element of cc. */ } /* End of js loop. */ /* Do LU decomposition of matrix block for grid point (ix,jy). */ ret = denseGETRF(Pxy, ns, ns, (webdata->pivot)[ix][jy]); if (ret != 0) return(1); } /* End of ix loop. */ } /* End of jy loop. */ return(0); }
static int PrecSetupBD(N_Vector cc, N_Vector cscale, N_Vector fval, N_Vector fscale, void *user_data, N_Vector vtemp1, N_Vector vtemp2) { realtype r, r0, uround, sqruround, xx, yy, delx, dely, csave, fac; realtype *cxy, *scxy, **Pxy, *ratesxy, *Pxycol, perturb_rates[NUM_SPECIES]; long int i, j, jx, jy, ret; UserData data; data = (UserData) user_data; delx = data->dx; dely = data->dy; uround = data->uround; sqruround = data->sqruround; fac = N_VWL2Norm(fval, fscale); r0 = THOUSAND * uround * fac * NEQ; if(r0 == ZERO) r0 = ONE; /* Loop over spatial points; get size NUM_SPECIES Jacobian block at each */ for (jy = 0; jy < MY; jy++) { yy = jy*dely; for (jx = 0; jx < MX; jx++) { xx = jx*delx; Pxy = (data->P)[jx][jy]; cxy = IJ_Vptr(cc,jx,jy); scxy= IJ_Vptr(cscale,jx,jy); ratesxy = IJ_Vptr((data->rates),jx,jy); /* Compute difference quotients of interaction rate fn. */ for (j = 0; j < NUM_SPECIES; j++) { csave = cxy[j]; /* Save the j,jx,jy element of cc */ r = SUNMAX(sqruround*SUNRabs(csave), r0/scxy[j]); cxy[j] += r; /* Perturb the j,jx,jy element of cc */ fac = ONE/r; WebRate(xx, yy, cxy, perturb_rates, data); /* Restore j,jx,jy element of cc */ cxy[j] = csave; /* Load the j-th column of difference quotients */ Pxycol = Pxy[j]; #pragma omp parallel for default(shared) private(i) for (i = 0; i < NUM_SPECIES; i++) Pxycol[i] = (perturb_rates[i] - ratesxy[i]) * fac; } /* end of j loop */ /* Do LU decomposition of size NUM_SPECIES preconditioner block */ ret = denseGETRF(Pxy, NUM_SPECIES, NUM_SPECIES, (data->pivot)[jx][jy]); if (ret != 0) return(1); } /* end of jx loop */ } /* end of jy loop */ return(0); }
static int Precond(realtype tt, N_Vector cc, N_Vector cp, N_Vector rr, realtype cj, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) { int flag; realtype uround, xx, yy, del_x, del_y; realtype **Pxy, *ratesxy, *Pxycol, *cxy, *cpxy, *ewtxy, cctmp; realtype inc, fac, sqru, perturb_rates[NUM_SPECIES]; int is, js, jx, jy, ret; void *mem; N_Vector ewt; realtype hh; UserData webdata; webdata = (UserData) user_data; del_x = webdata->dx; del_y = webdata->dy; uround = UNIT_ROUNDOFF; sqru = SUNRsqrt(uround); mem = webdata->ida_mem; ewt = webdata->ewt; flag = IDAGetErrWeights(mem, ewt); if(check_flag(&flag, "IDAGetErrWeights", 1)) return(1); flag = IDAGetCurrentStep(mem, &hh); if(check_flag(&flag, "IDAGetCurrentStep", 1)) return(1); for (jy = 0; jy < MY; jy++) { yy = jy * del_y; for (jx = 0; jx < MX; jx++) { xx = jx * del_x; Pxy = (webdata->PP)[jx][jy]; cxy = IJ_Vptr(cc, jx, jy); cpxy = IJ_Vptr(cp, jx, jy); ewtxy = IJ_Vptr(ewt, jx, jy); ratesxy = IJ_Vptr((webdata->rates), jx, jy); for (js = 0; js < NUM_SPECIES; js++) { inc = sqru*(SUNMAX(SUNRabs(cxy[js]), SUNMAX(hh*SUNRabs(cpxy[js]), ONE/ewtxy[js]))); cctmp = cxy[js]; cxy[js] += inc; fac = -ONE/inc; WebRates(xx, yy, cxy, perturb_rates, webdata); Pxycol = Pxy[js]; for (is = 0; is < NUM_SPECIES; is++) Pxycol[is] = (perturb_rates[is] - ratesxy[is])*fac; if (js < 1) Pxycol[js] += cj; cxy[js] = cctmp; } ret = denseGETRF(Pxy, NUM_SPECIES, NUM_SPECIES, (webdata->pivot)[jx][jy]); if (ret != 0) return(1); } } return(0); }