/*----------------------------------------------------------------- cvLsSetup This conditionally calls the LS 'setup' routine. When using a SUNMatrix object, this determines whether to update a Jacobian matrix (or use a stored version), based on heuristics regarding previous convergence issues, the number of time steps since it was last updated, etc.; it then creates the system matrix from this, the 'gamma' factor and the identity matrix, A = I-gamma*J. This routine then calls the LS 'setup' routine with A. -----------------------------------------------------------------*/ int cvLsSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, N_Vector fpred, booleantype *jcurPtr, N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3) { CVLsMem cvls_mem; realtype dgamma; int retval; /* access CVLsMem structure */ if (cv_mem->cv_lmem==NULL) { cvProcessError(cv_mem, CVLS_LMEM_NULL, "CVLS", "cvLsSetup", MSG_LS_LMEM_NULL); return(CVLS_LMEM_NULL); } cvls_mem = (CVLsMem) cv_mem->cv_lmem; /* Set CVLs N_Vector pointers to current solution and rhs */ cvls_mem->ycur = ypred; cvls_mem->fcur = fpred; /* Use nst, gamma/gammap, and convfail to set J/P eval. flag jok */ dgamma = SUNRabs((cv_mem->cv_gamma/cv_mem->cv_gammap) - ONE); cvls_mem->jbad = (cv_mem->cv_nst == 0) || (cv_mem->cv_nst > cvls_mem->nstlj + cvls_mem->msbj) || ((convfail == CV_FAIL_BAD_J) && (dgamma < CVLS_DGMAX)) || (convfail == CV_FAIL_OTHER); /* If using a NULL SUNMatrix, set jcur to jbad; otherwise update J as appropriate */ if (cvls_mem->A == NULL) { *jcurPtr = cvls_mem->jbad; } else { /* If jbad = SUNFALSE, use saved copy of J */ if (!cvls_mem->jbad) { *jcurPtr = SUNFALSE; retval = SUNMatCopy(cvls_mem->savedJ, cvls_mem->A); if (retval) { cvProcessError(cv_mem, CVLS_SUNMAT_FAIL, "CVLS", "cvLsSetup", MSG_LS_SUNMAT_FAILED); cvls_mem->last_flag = CVLS_SUNMAT_FAIL; return(cvls_mem->last_flag); } /* If jbad = SUNTRUE, call jac routine for new J value */ } else { cvls_mem->nje++; cvls_mem->nstlj = cv_mem->cv_nst; *jcurPtr = SUNTRUE; retval = SUNMatZero(cvls_mem->A); if (retval) { cvProcessError(cv_mem, CVLS_SUNMAT_FAIL, "CVLS", "cvLsSetup", MSG_LS_SUNMAT_FAILED); cvls_mem->last_flag = CVLS_SUNMAT_FAIL; return(cvls_mem->last_flag); } retval = cvls_mem->jac(cv_mem->cv_tn, ypred, fpred, cvls_mem->A, cvls_mem->J_data, vtemp1, vtemp2, vtemp3); if (retval < 0) { cvProcessError(cv_mem, CVLS_JACFUNC_UNRECVR, "CVLS", "cvLsSetup", MSG_LS_JACFUNC_FAILED); cvls_mem->last_flag = CVLS_JACFUNC_UNRECVR; return(-1); } if (retval > 0) { cvls_mem->last_flag = CVLS_JACFUNC_RECVR; return(1); } retval = SUNMatCopy(cvls_mem->A, cvls_mem->savedJ); if (retval) { cvProcessError(cv_mem, CVLS_SUNMAT_FAIL, "CVLS", "cvLsSetup", MSG_LS_SUNMAT_FAILED); cvls_mem->last_flag = CVLS_SUNMAT_FAIL; return(cvls_mem->last_flag); } } /* Scale and add I to get A = I - gamma*J */ retval = SUNMatScaleAddI(-cv_mem->cv_gamma, cvls_mem->A); if (retval) { cvProcessError(cv_mem, CVLS_SUNMAT_FAIL, "CVLS", "cvLsSetup", MSG_LS_SUNMAT_FAILED); cvls_mem->last_flag = CVLS_SUNMAT_FAIL; return(cvls_mem->last_flag); } } /* Call LS setup routine -- the LS may call cvLsPSetup, who will pass the heuristic suggestions above to the user code(s) */ cvls_mem->last_flag = SUNLinSolSetup(cvls_mem->LS, cvls_mem->A); /* If the SUNMatrix was NULL, update heuristics flags */ if (cvls_mem->A == NULL) { /* If user set jcur to SUNTRUE, increment npe and save nst value */ if (*jcurPtr) { cvls_mem->npe++; cvls_mem->nstlj = cv_mem->cv_nst; } /* Update jcur flag if we suggested an update */ if (cvls_mem->jbad) *jcurPtr = SUNTRUE; } return(cvls_mem->last_flag); }
/*----------------------------------------------------------------- cvDlsSetup ----------------------------------------------------------------- This routine determines whether to update a Jacobian matrix (or use a stored version), based on heuristics regarding previous convergence issues, the number of time steps since it was last updated, etc.; it then creates the system matrix from this, the 'gamma' factor and the identity matrix, A = I-gamma*J. This routine then calls the LS 'setup' routine with A. -----------------------------------------------------------------*/ int cvDlsSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, N_Vector fpred, booleantype *jcurPtr, N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3) { booleantype jbad, jok; realtype dgamma; CVDlsMem cvdls_mem; int retval; /* Return immediately if cv_mem or cv_mem->cv_lmem are NULL */ if (cv_mem == NULL) { cvProcessError(NULL, CVDLS_MEM_NULL, "CVDLS", "cvDlsSetup", MSGD_CVMEM_NULL); return(CVDLS_MEM_NULL); } if (cv_mem->cv_lmem == NULL) { cvProcessError(cv_mem, CVDLS_LMEM_NULL, "CVDLS", "cvDlsSetup", MSGD_LMEM_NULL); return(CVDLS_LMEM_NULL); } cvdls_mem = (CVDlsMem) cv_mem->cv_lmem; /* Use nst, gamma/gammap, and convfail to set J eval. flag jok */ dgamma = SUNRabs((cv_mem->cv_gamma/cv_mem->cv_gammap) - ONE); jbad = (cv_mem->cv_nst == 0) || (cv_mem->cv_nst > cvdls_mem->nstlj + CVD_MSBJ) || ((convfail == CV_FAIL_BAD_J) && (dgamma < CVD_DGMAX)) || (convfail == CV_FAIL_OTHER); jok = !jbad; /* If jok = SUNTRUE, use saved copy of J */ if (jok) { *jcurPtr = SUNFALSE; retval = SUNMatCopy(cvdls_mem->savedJ, cvdls_mem->A); if (retval) { cvProcessError(cv_mem, CVDLS_SUNMAT_FAIL, "CVDLS", "cvDlsSetup", MSGD_MATCOPY_FAILED); cvdls_mem->last_flag = CVDLS_SUNMAT_FAIL; return(-1); } /* If jok = SUNFALSE, call jac routine for new J value */ } else { cvdls_mem->nje++; cvdls_mem->nstlj = cv_mem->cv_nst; *jcurPtr = SUNTRUE; retval = SUNMatZero(cvdls_mem->A); if (retval) { cvProcessError(cv_mem, CVDLS_SUNMAT_FAIL, "CVDLS", "cvDlsSetup", MSGD_MATZERO_FAILED); cvdls_mem->last_flag = CVDLS_SUNMAT_FAIL; return(-1); } retval = cvdls_mem->jac(cv_mem->cv_tn, ypred, fpred, cvdls_mem->A, cvdls_mem->J_data, vtemp1, vtemp2, vtemp3); if (retval < 0) { cvProcessError(cv_mem, CVDLS_JACFUNC_UNRECVR, "CVDLS", "cvDlsSetup", MSGD_JACFUNC_FAILED); cvdls_mem->last_flag = CVDLS_JACFUNC_UNRECVR; return(-1); } if (retval > 0) { cvdls_mem->last_flag = CVDLS_JACFUNC_RECVR; return(1); } retval = SUNMatCopy(cvdls_mem->A, cvdls_mem->savedJ); if (retval) { cvProcessError(cv_mem, CVDLS_SUNMAT_FAIL, "CVDLS", "cvDlsSetup", MSGD_MATCOPY_FAILED); cvdls_mem->last_flag = CVDLS_SUNMAT_FAIL; return(-1); } } /* Scale and add I to get A = I - gamma*J */ retval = SUNMatScaleAddI(-cv_mem->cv_gamma, cvdls_mem->A); if (retval) { cvProcessError(cv_mem, CVDLS_SUNMAT_FAIL, "CVDLS", "cvDlsSetup", MSGD_MATSCALEADDI_FAILED); cvdls_mem->last_flag = CVDLS_SUNMAT_FAIL; return(-1); } /* Call generic linear solver 'setup' with this system matrix, and return success/failure flag */ cvdls_mem->last_flag = SUNLinSolSetup(cvdls_mem->LS, cvdls_mem->A); return(cvdls_mem->last_flag); }