int main() { int f = 0; int count = 0; int *matToMem = (int *)malloc(20000000); to_mem(matToMem, 0); int t=1; while(count < 1000) { int random = rand()%2; if(random == 0) { to_mem(matToMem, t); t++; } else { from_mem(matToMem, f); if(f < t-1) f++; } count++; } }
void SundialsInterface::print_stats(IntegratorMemory* mem, ostream &stream) const { auto m = to_mem(mem); stream << "FORWARD INTEGRATION:" << endl; stream << "Number of steps taken by SUNDIALS: " << m->nsteps << endl; stream << "Number of calls to the user’s f function: " << m->nfevals << endl; stream << "Number of calls made to the linear solver setup function: " << m->nlinsetups << endl; stream << "Number of error test failures: " << m->netfails << endl; stream << "Method order used on the last internal step: " << m->qlast << endl; stream << "Method order to be used on the next internal step: " << m->qcur << endl; stream << "Actual value of initial step size: " << m->hinused << endl; stream << "Step size taken on the last internal step: " << m->hlast << endl; stream << "Step size to be attempted on the next internal step: " << m->hcur << endl; stream << "Current internal time reached: " << m->tcur << endl; stream << "Number of nonlinear iterations performed: " << m->nniters << endl; stream << "Number of nonlinear convergence failures: " << m->nncfails << endl; if (nrx_>0) { stream << "BACKWARD INTEGRATION:" << endl; stream << "Number of steps taken by SUNDIALS: " << m->nstepsB << endl; stream << "Number of calls to the user’s f function: " << m->nfevalsB << endl; stream << "Number of calls made to the linear solver setup function: " << m->nlinsetupsB << endl; stream << "Number of error test failures: " << m->netfailsB << endl; stream << "Method order used on the last internal step: " << m->qlastB << endl; stream << "Method order to be used on the next internal step: " << m->qcurB << endl; stream << "Actual value of initial step size: " << m->hinusedB << endl; stream << "Step size taken on the last internal step: " << m->hlastB << endl; stream << "Step size to be attempted on the next internal step: " << m->hcurB << endl; stream << "Current internal time reached: " << m->tcurB << endl; stream << "Number of nonlinear iterations performed: " << m->nnitersB << endl; stream << "Number of nonlinear convergence failures: " << m->nncfailsB << endl; } stream << endl; }
int IdasInterface::rhsQB(double t, N_Vector xz, N_Vector xzdot, N_Vector rxz, N_Vector rxzdot, N_Vector rqdot, void *user_data) { try { auto m = to_mem(user_data); auto& s = m->self; m->arg[0] = NV_DATA_S(rxz); m->arg[1] = NV_DATA_S(rxz)+s.nrx_; m->arg[2] = m->rp; m->arg[3] = NV_DATA_S(xz); m->arg[4] = NV_DATA_S(xz)+s.nx_; m->arg[5] = m->p; m->arg[6] = &t; m->res[0] = NV_DATA_S(rqdot); s.calc_function(m, "quadB"); // Negate (note definition of g) casadi_scal(s.nrq_, -1., NV_DATA_S(rqdot)); return 0; } catch(int flag) { // recoverable error return flag; } catch(exception& e) { // non-recoverable error userOut<true, PL_WARN>() << "resQB failed: " << e.what() << endl; return -1; } }
int IdasInterface::resB(double t, N_Vector xz, N_Vector xzdot, N_Vector rxz, N_Vector rxzdot, N_Vector rr, void *user_data) { try { auto m = to_mem(user_data); auto& s = m->self; m->arg[0] = NV_DATA_S(rxz); m->arg[1] = NV_DATA_S(rxz)+s.nrx_; m->arg[2] = m->rp; m->arg[3] = NV_DATA_S(xz); m->arg[4] = NV_DATA_S(xz)+s.nx_; m->arg[5] = m->p; m->arg[6] = &t; m->res[0] = NV_DATA_S(rr); m->res[1] = NV_DATA_S(rr)+s.nrx_; s.calc_function(m, "daeB"); // Subtract state derivative to get residual casadi_axpy(s.nrx_, 1., NV_DATA_S(rxzdot), NV_DATA_S(rr)); return 0; } catch(int flag) { // recoverable error return flag; } catch(exception& e) { // non-recoverable error userOut<true, PL_WARN>() << "resB failed: " << e.what() << endl; return -1; } }
int IdasInterface::lsolve(IDAMem IDA_mem, N_Vector b, N_Vector weight, N_Vector xz, N_Vector xzdot, N_Vector rr) { try { auto m = to_mem(IDA_mem->ida_lmem); auto& s = m->self; // Current time double t = IDA_mem->ida_tn; // Multiple of df_dydot to be added to the matrix double cj = IDA_mem->ida_cj; // Accuracy double delta = 0.0; // Call the preconditioner solve function (which solves the linear system) if (psolve(t, xz, xzdot, rr, b, b, cj, delta, static_cast<void*>(m), 0)) return 1; // Scale the correction to account for change in cj if (s.cj_scaling_) { double cjratio = IDA_mem->ida_cjratio; if (cjratio != 1.0) N_VScale(2.0/(1.0 + cjratio), b, b); } return 0; } catch(int flag) { // recoverable error return flag; } catch(exception& e) { // non-recoverable error userOut<true, PL_WARN>() << "lsolve failed: " << e.what() << endl; return -1; } }
int IdasInterface::psetupB(double t, N_Vector xz, N_Vector xzdot, N_Vector rxz, N_Vector rxzdot, N_Vector rresval, double cj, void *user_data, N_Vector tmp1B, N_Vector tmp2B, N_Vector tmp3B) { try { auto m = to_mem(user_data); auto& s = m->self; m->arg[0] = &t; m->arg[1] = NV_DATA_S(rxz); m->arg[2] = NV_DATA_S(rxz)+s.nrx_; m->arg[3] = m->rp; m->arg[4] = NV_DATA_S(xz); m->arg[5] = NV_DATA_S(xz)+s.nx_; m->arg[6] = m->p; m->arg[7] = &cj; m->res[0] = m->jacB; s.calc_function(m, "jacB"); // Factorize the linear system s.linsolB_.factorize(m->jacB); return 0; } catch(int flag) { // recoverable error return flag; } catch(exception& e) { // non-recoverable error userOut<true, PL_WARN>() << "psetupB failed: " << e.what() << endl; return -1; } }
void IdasInterface::retreat(IntegratorMemory* mem, double t, double* rx, double* rz, double* rq) const { auto m = to_mem(mem); // Integrate, unless already at desired time if (t<m->t) { THROWING(IDASolveB, m->mem, t, IDA_NORMAL); THROWING(IDAGetB, m->mem, m->whichB, &m->t, m->rxz, m->rxzdot); if (nrq_>0) { THROWING(IDAGetQuadB, m->mem, m->whichB, &m->t, m->rq); } } // Save outputs casadi_copy(NV_DATA_S(m->rxz), nrx_, rx); casadi_copy(NV_DATA_S(m->rxz)+nrx_, nrz_, rz); casadi_copy(NV_DATA_S(m->rq), nrq_, rq); // Get stats IDAMem IDA_mem = IDAMem(m->mem); IDAadjMem IDAADJ_mem = IDA_mem->ida_adj_mem; IDABMem IDAB_mem = IDAADJ_mem->IDAB_mem; THROWING(IDAGetIntegratorStats, IDAB_mem->IDA_mem, &m->nstepsB, &m->nfevalsB, &m->nlinsetupsB, &m->netfailsB, &m->qlastB, &m->qcurB, &m->hinusedB, &m->hlastB, &m->hcurB, &m->tcurB); }
int IdasInterface::jtimesB(double t, N_Vector xz, N_Vector xzdot, N_Vector xzB, N_Vector xzdotB, N_Vector resvalB, N_Vector vB, N_Vector JvB, double cjB, void *user_data, N_Vector tmp1B, N_Vector tmp2B) { try { auto m = to_mem(user_data); auto& s = m->self; m->arg[0] = &t; m->arg[1] = NV_DATA_S(xz); m->arg[2] = NV_DATA_S(xz)+s.nx_; m->arg[3] = m->p; m->arg[4] = NV_DATA_S(xzB); m->arg[5] = NV_DATA_S(xzB)+s.nrx_; m->arg[6] = m->rp; m->arg[7] = NV_DATA_S(vB); m->arg[8] = NV_DATA_S(vB)+s.nrx_; m->res[0] = NV_DATA_S(JvB); m->res[1] = NV_DATA_S(JvB) + s.nrx_; s.calc_function(m, "jtimesB"); // Subtract state derivative to get residual casadi_axpy(s.nrx_, cjB, NV_DATA_S(vB), NV_DATA_S(JvB)); return 0; } catch(int flag) { // recoverable error return flag; } catch(exception& e) { // non-recoverable error userOut<true, PL_WARN>() << "jtimesB failed: " << e.what() << endl; return -1; } }
void IdasInterface::reset(IntegratorMemory* mem, double t, const double* _x, const double* _z, const double* _p) const { log("IdasInterface::reset", "begin"); auto m = to_mem(mem); // Reset the base classes SundialsInterface::reset(mem, t, _x, _z, _p); // Re-initialize copy(init_xdot_.begin(), init_xdot_.end(), NV_DATA_S(m->xzdot)); THROWING(IDAReInit, m->mem, grid_.front(), m->xz, m->xzdot); // Re-initialize quadratures if (nq_>0) THROWING(IDAQuadReInit, m->mem, m->q); // Correct initial conditions, if necessary if (calc_ic_) { THROWING(IDACalcIC, m->mem, IDA_YA_YDP_INIT , first_time_); THROWING(IDAGetConsistentIC, m->mem, m->xz, m->xzdot); } // Re-initialize backward integration if (nrx_>0) THROWING(IDAAdjReInit, m->mem); // Set the stop time of the integration -- don't integrate past this point if (stop_at_end_) setStopTime(m, grid_.back()); log("IdasInterface::reset", "end"); }
int IdasInterface::lsolveB(IDAMem IDA_mem, N_Vector b, N_Vector weight, N_Vector xzB, N_Vector xzdotB, N_Vector rrB) { try { auto m = to_mem(IDA_mem->ida_lmem); auto& s = m->self; IDAadjMem IDAADJ_mem; //IDABMem IDAB_mem; int flag; // Current time double t = IDA_mem->ida_tn; // TODO(Joel): is this correct? // Multiple of df_dydot to be added to the matrix double cj = IDA_mem->ida_cj; double cjratio = IDA_mem->ida_cjratio; IDA_mem = (IDAMem) IDA_mem->ida_user_data; IDAADJ_mem = IDA_mem->ida_adj_mem; //IDAB_mem = IDAADJ_mem->ia_bckpbCrt; // Get FORWARD solution from interpolation. if (IDAADJ_mem->ia_noInterp==FALSE) { flag = IDAADJ_mem->ia_getY(IDA_mem, t, IDAADJ_mem->ia_yyTmp, IDAADJ_mem->ia_ypTmp, NULL, NULL); if (flag != IDA_SUCCESS) casadi_error("Could not interpolate forward states"); } // Accuracy double delta = 0.0; // Call the preconditioner solve function (which solves the linear system) if (psolveB(t, IDAADJ_mem->ia_yyTmp, IDAADJ_mem->ia_ypTmp, xzB, xzdotB, rrB, b, b, cj, delta, static_cast<void*>(m), 0)) return 1; // Scale the correction to account for change in cj if (s.cj_scaling_) { if (cjratio != 1.0) N_VScale(2.0/(1.0 + cjratio), b, b); } return 0; } catch(int flag) { // recoverable error return flag; } catch(exception& e) { // non-recoverable error userOut<true, PL_WARN>() << "lsolveB failed: " << e.what() << endl; return -1; } }
int IdasInterface::rhsQ(double t, N_Vector xz, N_Vector xzdot, N_Vector rhsQ, void *user_data) { try { auto m = to_mem(user_data); auto& s = m->self; m->arg[0] = NV_DATA_S(xz); m->arg[1] = NV_DATA_S(xz)+s.nx_; m->arg[2] = m->p; m->arg[3] = &t; m->res[0] = NV_DATA_S(rhsQ); s.calc_function(m, "quadF"); return 0; } catch(int flag) { // recoverable error return flag; } catch(exception& e) { // non-recoverable error userOut<true, PL_WARN>() << "rhsQ failed: " << e.what() << endl; return -1; } }
void IdasInterface:: advance(IntegratorMemory* mem, double t, double* x, double* z, double* q) const { auto m = to_mem(mem); casadi_assert_message(t>=grid_.front(), "IdasInterface::integrate(" << t << "): " "Cannot integrate to a time earlier than t0 (" << grid_.front() << ")"); casadi_assert_message(t<=grid_.back() || !stop_at_end_, "IdasInterface::integrate(" << t << "): " "Cannot integrate past a time later than tf (" << grid_.back() << ") " "unless stop_at_end is set to False."); // Integrate, unless already at desired time double ttol = 1e-9; // tolerance if (fabs(m->t-t)>=ttol) { // Integrate forward ... if (nrx_>0) { // ... with taping THROWING(IDASolveF, m->mem, t, &m->t, m->xz, m->xzdot, IDA_NORMAL, &m->ncheck); } else { // ... without taping THROWING(IDASolve, m->mem, t, &m->t, m->xz, m->xzdot, IDA_NORMAL); } // Get quadratures if (nq_>0) { double tret; THROWING(IDAGetQuad, m->mem, &tret, m->q); } } // Set function outputs casadi_copy(NV_DATA_S(m->xz), nx_, x); casadi_copy(NV_DATA_S(m->xz)+nx_, nz_, z); casadi_copy(NV_DATA_S(m->q), nq_, q); // Get stats THROWING(IDAGetIntegratorStats, m->mem, &m->nsteps, &m->nfevals, &m->nlinsetups, &m->netfails, &m->qlast, &m->qcur, &m->hinused, &m->hlast, &m->hcur, &m->tcur); THROWING(IDAGetNonlinSolvStats, m->mem, &m->nniters, &m->nncfails); }
int IdasInterface::lsetupB(IDAMem IDA_mem, N_Vector xzB, N_Vector xzdotB, N_Vector respB, N_Vector vtemp1B, N_Vector vtemp2B, N_Vector vtemp3B) { try { auto m = to_mem(IDA_mem->ida_lmem); //auto& s = m->self; IDAadjMem IDAADJ_mem; //IDABMem IDAB_mem; // Current time double t = IDA_mem->ida_tn; // TODO(Joel): is this correct? // Multiple of df_dydot to be added to the matrix double cj = IDA_mem->ida_cj; IDA_mem = static_cast<IDAMem>(IDA_mem->ida_user_data); IDAADJ_mem = IDA_mem->ida_adj_mem; //IDAB_mem = IDAADJ_mem->ia_bckpbCrt; // Get FORWARD solution from interpolation. if (IDAADJ_mem->ia_noInterp==FALSE) { int flag = IDAADJ_mem->ia_getY(IDA_mem, t, IDAADJ_mem->ia_yyTmp, IDAADJ_mem->ia_ypTmp, NULL, NULL); if (flag != IDA_SUCCESS) casadi_error("Could not interpolate forward states"); } // Call the preconditioner setup function (which sets up the linear solver) if (psetupB(t, IDAADJ_mem->ia_yyTmp, IDAADJ_mem->ia_ypTmp, xzB, xzdotB, 0, cj, static_cast<void*>(m), vtemp1B, vtemp1B, vtemp3B)) return 1; return 0; } catch(int flag) { // recoverable error return flag; } catch(exception& e) { // non-recoverable error userOut<true, PL_WARN>() << "lsetupB failed: " << e.what() << endl; return -1; } }
int IdasInterface::psolveB(double t, N_Vector xz, N_Vector xzdot, N_Vector xzB, N_Vector xzdotB, N_Vector resvalB, N_Vector rvecB, N_Vector zvecB, double cjB, double deltaB, void *user_data, N_Vector tmpB) { try { auto m = to_mem(user_data); auto& s = m->self; // Get right-hand sides in m->v1, ordered by sensitivity directions double* vx = NV_DATA_S(rvecB); double* vz = vx + s.nrx_; double* v_it = m->v1; for (int d=0; d<=s.ns_; ++d) { casadi_copy(vx + d*s.nrx1_, s.nrx1_, v_it); v_it += s.nrx1_; casadi_copy(vz + d*s.nrz1_, s.nrz1_, v_it); v_it += s.nrz1_; } // Solve for undifferentiated right-hand-side, save to output s.linsolB_.solve(m->v1, 1); vx = NV_DATA_S(zvecB); // possibly different from rvecB vz = vx + s.nrx_; casadi_copy(m->v1, s.nrx1_, vx); casadi_copy(m->v1 + s.nrx1_, s.nrz1_, vz); // Sensitivity equations if (s.ns_>0) { // Second order correction if (s.second_order_correction_) { // The outputs will double as seeds for jtimesB casadi_fill(vx + s.nrx1_, s.nrx_ - s.nrx1_, 0.); casadi_fill(vz + s.nrz1_, s.nrz_ - s.nrz1_, 0.); // Get second-order-correction, save to m->v2 m->arg[0] = &t; // t m->arg[1] = NV_DATA_S(xz); // x m->arg[2] = NV_DATA_S(xz)+s.nx_; // z m->arg[3] = m->p; // p m->arg[4] = NV_DATA_S(xzB); // rx m->arg[5] = NV_DATA_S(xzB)+s.nrx_; // rz m->arg[6] = m->rp; // rp m->arg[7] = vx; // fwd:rx m->arg[8] = vz; // fwd:rz m->res[0] = m->v2; // fwd:rode m->res[1] = m->v2 + s.nrx_; // fwd:ralg s.calc_function(m, "jtimesB"); // Subtract m->v2 (reordered) from m->v1 v_it = m->v1 + s.nrx1_ + s.nrz1_; for (int d=1; d<=s.ns_; ++d) { casadi_axpy(s.nrx1_, -1., m->v2 + d*s.nrx1_, v_it); v_it += s.nrx1_; casadi_axpy(s.nrz1_, -1., m->v2 + s.nrx_ + d*s.nrz1_, v_it); v_it += s.nrz1_; } } // Solve for sensitivity right-hand-sides s.linsolB_.solve(m->v1 + s.nrx1_ + s.nrz1_, s.ns_); // Save to output, reordered v_it = m->v1 + s.nrx1_ + s.nrz1_; for (int d=1; d<=s.ns_; ++d) { casadi_copy(v_it, s.nrx1_, vx + d*s.nrx1_); v_it += s.nrx1_; casadi_copy(v_it, s.nrz1_, vz + d*s.nrz1_); v_it += s.nrz1_; } } return 0; } catch(int flag) { // recoverable error return flag; } catch(exception& e) { // non-recoverable error userOut<true, PL_WARN>() << "psolveB failed: " << e.what() << endl; return -1; } }
void IdasInterface::setStopTime(IntegratorMemory* mem, double tf) const { // Set the stop time of the integration -- don't integrate past this point auto m = to_mem(mem); //auto& s = m->self; THROWING(IDASetStopTime, m->mem, tf); }
void IdasInterface::resetB(IntegratorMemory* mem, double t, const double* rx, const double* rz, const double* rp) const { log("IdasInterface::resetB", "begin"); auto m = to_mem(mem); // Reset the base classes SundialsInterface::resetB(mem, t, rx, rz, rp); if (m->first_callB) { // Create backward problem THROWING(IDACreateB, m->mem, &m->whichB); THROWING(IDAInitB, m->mem, m->whichB, resB, grid_.back(), m->rxz, m->rxzdot); THROWING(IDASStolerancesB, m->mem, m->whichB, reltol_, abstol_); THROWING(IDASetUserDataB, m->mem, m->whichB, m); THROWING(IDASetMaxNumStepsB, m->mem, m->whichB, max_num_steps_); // Set algebraic components N_Vector id = N_VNew_Serial(nrx_+nrz_); fill_n(NV_DATA_S(id), nrx_, 1); fill_n(NV_DATA_S(id)+nrx_, nrz_, 0); THROWING(IDASetIdB, m->mem, m->whichB, id); N_VDestroy_Serial(id); // attach linear solver if (newton_scheme_==SD_DIRECT) { // Direct scheme IDAMem IDA_mem = IDAMem(m->mem); IDAadjMem IDAADJ_mem = IDA_mem->ida_adj_mem; IDABMem IDAB_mem = IDAADJ_mem->IDAB_mem; IDAB_mem->ida_lmem = m; IDAB_mem->IDA_mem->ida_lmem = m; IDAB_mem->IDA_mem->ida_lsetup = lsetupB; IDAB_mem->IDA_mem->ida_lsolve = lsolveB; IDAB_mem->IDA_mem->ida_setupNonNull = TRUE; } else { // Iterative scheme switch (newton_scheme_) { case SD_DIRECT: casadi_assert(0); case SD_GMRES: THROWING(IDASpgmrB, m->mem, m->whichB, max_krylov_); break; case SD_BCGSTAB: THROWING(IDASpbcgB, m->mem, m->whichB, max_krylov_); break; case SD_TFQMR: THROWING(IDASptfqmrB, m->mem, m->whichB, max_krylov_); break; } THROWING(IDASpilsSetJacTimesVecFnB, m->mem, m->whichB, jtimesB); if (use_precon_) THROWING(IDASpilsSetPreconditionerB, m->mem, m->whichB, psetupB, psolveB); } // Quadratures for the adjoint problem THROWING(IDAQuadInitB, m->mem, m->whichB, rhsQB, m->rq); if (quad_err_con_) { THROWING(IDASetQuadErrConB, m->mem, m->whichB, true); THROWING(IDAQuadSStolerancesB, m->mem, m->whichB, reltol_, abstol_); } // Mark initialized m->first_callB = false; } else { // Re-initialize THROWING(IDAReInitB, m->mem, m->whichB, grid_.back(), m->rxz, m->rxzdot); if (nrq_>0) { // Workaround (bug in SUNDIALS) // THROWING(IDAQuadReInitB, m->mem, m->whichB[dir], m->rq[dir]); void* memB = IDAGetAdjIDABmem(m->mem, m->whichB); THROWING(IDAQuadReInit, memB, m->rq); } } // Correct initial values for the integration if necessary if (calc_icB_) { THROWING(IDACalcICB, m->mem, m->whichB, grid_.front(), m->xz, m->xzdot); THROWING(IDAGetConsistentICB, m->mem, m->whichB, m->rxz, m->rxzdot); } log("IdasInterface::resetB", "end"); }
void IdasInterface::init_memory(void* mem) const { SundialsInterface::init_memory(mem); auto m = to_mem(mem); // Create IDAS memory block m->mem = IDACreate(); casadi_assert_message(m->mem!=0, "IDACreate: Creation failed"); // Set error handler function THROWING(IDASetErrHandlerFn, m->mem, ehfun, m); // Set user data THROWING(IDASetUserData, m->mem, m); // Allocate n-vectors for ivp m->xzdot = N_VNew_Serial(nx_+nz_); // Initialize Idas double t0 = 0; N_VConst(0.0, m->xz); N_VConst(0.0, m->xzdot); IDAInit(m->mem, res, t0, m->xz, m->xzdot); log("IdasInterface::init", "IDA initialized"); // Include algebraic variables in error testing THROWING(IDASetSuppressAlg, m->mem, suppress_algebraic_); // Maxinum order for the multistep method THROWING(IDASetMaxOrd, m->mem, max_multistep_order_); // Set maximum step size THROWING(IDASetMaxStep, m->mem, max_step_size_); // Initial step size if (step0_) THROWING(IDASetInitStep, m->mem, step0_); // Maximum order of method if (max_order_) THROWING(IDASetMaxOrd, m->mem, max_order_); // Coeff. in the nonlinear convergence test if (nonlin_conv_coeff_) THROWING(IDASetNonlinConvCoef, m->mem, nonlin_conv_coeff_); if (!abstolv_.empty()) { // Vector absolute tolerances N_Vector nv_abstol = N_VNew_Serial(abstolv_.size()); copy(abstolv_.begin(), abstolv_.end(), NV_DATA_S(nv_abstol)); THROWING(IDASVtolerances, m->mem, reltol_, nv_abstol); N_VDestroy_Serial(nv_abstol); } else { // Scalar absolute tolerances THROWING(IDASStolerances, m->mem, reltol_, abstol_); } // Maximum number of steps THROWING(IDASetMaxNumSteps, m->mem, max_num_steps_); // Set algebraic components N_Vector id = N_VNew_Serial(nx_+nz_); fill_n(NV_DATA_S(id), nx_, 1); fill_n(NV_DATA_S(id)+nx_, nz_, 0); // Pass this information to IDAS THROWING(IDASetId, m->mem, id); // Delete the allocated memory N_VDestroy_Serial(id); // attach a linear solver if (newton_scheme_==SD_DIRECT) { // Direct scheme IDAMem IDA_mem = IDAMem(m->mem); IDA_mem->ida_lmem = m; IDA_mem->ida_lsetup = lsetup; IDA_mem->ida_lsolve = lsolve; IDA_mem->ida_setupNonNull = TRUE; } else { // Iterative scheme switch (newton_scheme_) { case SD_DIRECT: casadi_assert(0); case SD_GMRES: THROWING(IDASpgmr, m->mem, max_krylov_); break; case SD_BCGSTAB: THROWING(IDASpbcg, m->mem, max_krylov_); break; case SD_TFQMR: THROWING(IDASptfqmr, m->mem, max_krylov_); break; } THROWING(IDASpilsSetJacTimesVecFn, m->mem, jtimes); if (use_precon_) THROWING(IDASpilsSetPreconditioner, m->mem, psetup, psolve); } // Quadrature equations if (nq_>0) { // Initialize quadratures in IDAS THROWING(IDAQuadInit, m->mem, rhsQ, m->q); // Should the quadrature errors be used for step size control? if (quad_err_con_) { THROWING(IDASetQuadErrCon, m->mem, true); // Quadrature error tolerances // TODO(Joel): vector absolute tolerances THROWING(IDAQuadSStolerances, m->mem, reltol_, abstol_); } } log("IdasInterface::init", "attached linear solver"); // Adjoint sensitivity problem if (nrx_>0) { m->rxzdot = N_VNew_Serial(nrx_+nrz_); N_VConst(0.0, m->rxz); N_VConst(0.0, m->rxzdot); } log("IdasInterface::init", "initialized adjoint sensitivities"); // Initialize adjoint sensitivities if (nrx_>0) { int interpType = interp_==SD_HERMITE ? IDA_HERMITE : IDA_POLYNOMIAL; THROWING(IDAAdjInit, m->mem, steps_per_checkpoint_, interpType); } m->first_callB = true; }