static void CVDenseDQJac(integertype N, DenseMat J, RhsFn f, void *f_data, realtype tn, N_Vector y, N_Vector fy, N_Vector ewt, realtype h, realtype uround, void *jac_data, long int *nfePtr, N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3) { realtype fnorm, minInc, inc, inc_inv, yjsaved, srur; realtype *y_data, *ewt_data; N_Vector ftemp, jthCol; M_Env machEnv; integertype j; machEnv = y->menv; /* Get machine environment */ ftemp = vtemp1; /* Rename work vector for use as f vector value */ /* Obtain pointers to the data for ewt, y */ ewt_data = N_VGetData(ewt); y_data = N_VGetData(y); /* Set minimum increment based on uround and norm of f */ srur = RSqrt(uround); fnorm = N_VWrmsNorm(fy, ewt); minInc = (fnorm != ZERO) ? (MIN_INC_MULT * ABS(h) * uround * N * fnorm) : ONE; jthCol = N_VMake(N, y_data, machEnv); /* j loop overwrites this data address */ /* This is the only for loop for 0..N-1 in CVODE */ for (j = 0; j < N; j++) { /* Generate the jth col of J(tn,y) */ N_VSetData(DENSE_COL(J, j), jthCol); yjsaved = y_data[j]; inc = MAX(srur * ABS(yjsaved), minInc / ewt_data[j]); y_data[j] += inc; f(N, tn, y, ftemp, f_data); inc_inv = ONE / inc; N_VLinearSum(inc_inv, ftemp, -inc_inv, fy, jthCol); y_data[j] = yjsaved; } N_VDispose(jthCol); /* Increment counter nfe = *nfePtr */ *nfePtr += N; }
static int CVDenseSolve(CVodeMem cv_mem, N_Vector b, N_Vector ycur, N_Vector fcur) { CVDenseMem cvdense_mem; realtype *bd; cvdense_mem = (CVDenseMem) lmem; bd = N_VGetData(b); DenseBacksolve(M, pivots, bd); N_VSetData(bd, b); /* If BDF, scale the correction to account for change in gamma */ if ((lmm == BDF) && (gamrat != ONE)) { N_VScale(TWO/(ONE + gamrat), b, b); } return(0); }