void FIDA_REINIT(realtype *t0, realtype *yy0, realtype *yp0, int *iatol, realtype *rtol, realtype *atol, int *ier) { N_Vector Vatol; *ier = 0; /* Initialize all pointers to NULL */ Vatol = NULL; /* Attach user's yy0 to F2C_IDA_vec */ N_VSetArrayPointer(yy0, F2C_IDA_vec); /* Attach user's yp0 to F2C_IDA_ypvec */ N_VSetArrayPointer(yp0, F2C_IDA_ypvec); /* Call IDAReInit */ *ier = IDAReInit(IDA_idamem, *t0, F2C_IDA_vec, F2C_IDA_ypvec); /* Reset data pointers */ N_VSetArrayPointer(NULL, F2C_IDA_vec); N_VSetArrayPointer(NULL, F2C_IDA_ypvec); /* On failure, exit */ if (*ier != IDA_SUCCESS) { *ier = -1; return; } /* Set tolerances */ switch (*iatol) { case 1: *ier = IDASStolerances(IDA_idamem, *rtol, *atol); break; case 2: Vatol = NULL; Vatol= N_VCloneEmpty(F2C_IDA_vec); if (Vatol == NULL) { *ier = -1; return; } N_VSetArrayPointer(atol, Vatol); *ier = IDASVtolerances(IDA_idamem, *rtol, Vatol); N_VDestroy(Vatol); break; } /* On failure, exit */ if (*ier != IDA_SUCCESS) { *ier = -1; return; } return; }
void FIDA_TOLREINIT(int *iatol, realtype *rtol, realtype *atol, int *ier) { N_Vector Vatol=NULL; *ier = 0; if (*iatol == 1) { *ier = IDASStolerances(IDA_idamem, *rtol, *atol); } else { Vatol = NULL; Vatol = N_VCloneEmpty(F2C_IDA_vec); if (Vatol == NULL) { *ier = -1; return; } N_VSetArrayPointer(atol, Vatol); *ier = IDASVtolerances(IDA_idamem, *rtol, Vatol); N_VDestroy(Vatol); } return; }
void FIDA_MALLOC(realtype *t0, realtype *yy0, realtype *yp0, int *iatol, realtype *rtol, realtype *atol, long int *iout, realtype *rout, long int *ipar, realtype *rpar, int *ier) { N_Vector Vatol; FIDAUserData IDA_userdata; *ier = 0; /* Check for required vector operations */ if ((F2C_IDA_vec->ops->nvgetarraypointer == NULL) || (F2C_IDA_vec->ops->nvsetarraypointer == NULL)) { *ier = -1; printf("A required vector operation is not implemented.\n\n"); return; } /* Initialize all pointers to NULL */ IDA_idamem = NULL; Vatol = NULL; F2C_IDA_ypvec = F2C_IDA_ewtvec = NULL; /* Create IDA object */ IDA_idamem = IDACreate(); if (IDA_idamem == NULL) { *ier = -1; return; } /* Set and attach user data */ IDA_userdata = NULL; IDA_userdata = (FIDAUserData) malloc(sizeof *IDA_userdata); if (IDA_userdata == NULL) { *ier = -1; return; } IDA_userdata->rpar = rpar; IDA_userdata->ipar = ipar; *ier = IDASetUserData(IDA_idamem, IDA_userdata); if(*ier != IDA_SUCCESS) { free(IDA_userdata); IDA_userdata = NULL; *ier = -1; return; } /* Attach user's yy0 to F2C_IDA_vec */ N_VSetArrayPointer(yy0, F2C_IDA_vec); /* Create F2C_IDA_ypvec and attach user's yp0 to it */ F2C_IDA_ypvec = NULL; F2C_IDA_ypvec = N_VCloneEmpty(F2C_IDA_vec); if (F2C_IDA_ypvec == NULL) { free(IDA_userdata); IDA_userdata = NULL; *ier = -1; } N_VSetArrayPointer(yp0, F2C_IDA_ypvec); /* Call IDAInit */ *ier = IDAInit(IDA_idamem, FIDAresfn, *t0, F2C_IDA_vec, F2C_IDA_ypvec); /* Reset data pointers */ N_VSetArrayPointer(NULL, F2C_IDA_vec); N_VSetArrayPointer(NULL, F2C_IDA_ypvec); /* On failure, clean-up and exit */ if (*ier != IDA_SUCCESS) { N_VDestroy(F2C_IDA_ypvec); free(IDA_userdata); IDA_userdata = NULL; *ier = -1; return; } /* Set tolerances */ switch (*iatol) { case 1: *ier = IDASStolerances(IDA_idamem, *rtol, *atol); break; case 2: Vatol = NULL; Vatol= N_VCloneEmpty(F2C_IDA_vec); if (Vatol == NULL) { free(IDA_userdata); IDA_userdata = NULL; *ier = -1; return; } N_VSetArrayPointer(atol, Vatol); *ier = IDASVtolerances(IDA_idamem, *rtol, Vatol); N_VDestroy(Vatol); break; } /* On failure, clean-up and exit */ if (*ier != IDA_SUCCESS) { free(IDA_userdata); IDA_userdata = NULL; *ier = -1; return; } /* Grab optional output arrays and store them in global variables */ IDA_iout = iout; IDA_rout = rout; /* Store the unit roundoff in rout for user access */ IDA_rout[5] = UNIT_ROUNDOFF; /* Set F2C_IDA_ewtvec on NULL */ F2C_IDA_ewtvec = NULL; return; }
int main(void) { void *mem; N_Vector yy, yp, avtol; realtype rtol, *yval, *ypval, *atval; realtype t0, tout1, tout, tret; int iout, retval, retvalr; int rootsfound[2]; int nnz; mem = NULL; yy = yp = avtol = NULL; yval = ypval = atval = NULL; /* Allocate N-vectors. */ yy = N_VNew_Serial(NEQ); if(check_flag((void *)yy, "N_VNew_Serial", 0)) return(1); yp = N_VNew_Serial(NEQ); if(check_flag((void *)yp, "N_VNew_Serial", 0)) return(1); avtol = N_VNew_Serial(NEQ); if(check_flag((void *)avtol, "N_VNew_Serial", 0)) return(1); /* Create and initialize y, y', and absolute tolerance vectors. */ yval = NV_DATA_S(yy); yval[0] = ONE; yval[1] = ZERO; yval[2] = ZERO; ypval = NV_DATA_S(yp); ypval[0] = RCONST(-0.04); ypval[1] = RCONST(0.04); ypval[2] = ZERO; rtol = RCONST(1.0e-4); atval = NV_DATA_S(avtol); atval[0] = RCONST(1.0e-8); atval[1] = RCONST(1.0e-6); atval[2] = RCONST(1.0e-6); /* Integration limits */ t0 = ZERO; tout1 = RCONST(0.4); PrintHeader(rtol, avtol, yy); /* Call IDACreate and IDAMalloc to initialize IDA memory */ mem = IDACreate(); if(check_flag((void *)mem, "IDACreate", 0)) return(1); retval = IDAInit(mem, resrob, t0, yy, yp); if(check_flag(&retval, "IDAInit", 1)) return(1); retval = IDASVtolerances(mem, rtol, avtol); if(check_flag(&retval, "IDASVtolerances", 1)) return(1); /* Free avtol */ N_VDestroy_Serial(avtol); /* Call IDARootInit to specify the root function grob with 2 components */ retval = IDARootInit(mem, 2, grob); if (check_flag(&retval, "IDARootInit", 1)) return(1); /* Call IDASuperLUMT and set up the linear solver. */ nnz = NEQ * NEQ; retval = IDASuperLUMT(mem, 1, NEQ, nnz); if(check_flag(&retval, "IDASuperLUMT", 1)) return(1); retval = IDASlsSetSparseJacFn(mem, jacrob); if(check_flag(&retval, "IDASlsSetSparseJacFn", 1)) return(1); /* In loop, call IDASolve, print results, and test for error. Break out of loop when NOUT preset output times have been reached. */ iout = 0; tout = tout1; while(1) { retval = IDASolve(mem, tout, &tret, yy, yp, IDA_NORMAL); PrintOutput(mem,tret,yy); if(check_flag(&retval, "IDASolve", 1)) return(1); if (retval == IDA_ROOT_RETURN) { retvalr = IDAGetRootInfo(mem, rootsfound); check_flag(&retvalr, "IDAGetRootInfo", 1); PrintRootInfo(rootsfound[0],rootsfound[1]); } if (retval == IDA_SUCCESS) { iout++; tout *= RCONST(10.0); } if (iout == NOUT) break; } PrintFinalStats(mem); /* Free memory */ IDAFree(&mem); N_VDestroy_Serial(yy); N_VDestroy_Serial(yp); return(0); }
int main(void) { void *mem; N_Vector yy, yp, avtol; realtype rtol, *yval, *ypval, *atval; realtype t0, tout1, tout, tret; int iout, retval, retvalr; int rootsfound[2]; SUNMatrix A; SUNLinearSolver LS; sunindextype nnz; mem = NULL; yy = yp = avtol = NULL; yval = ypval = atval = NULL; A = NULL; LS = NULL; /* Allocate N-vectors. */ yy = N_VNew_Serial(NEQ); if(check_retval((void *)yy, "N_VNew_Serial", 0)) return(1); yp = N_VNew_Serial(NEQ); if(check_retval((void *)yp, "N_VNew_Serial", 0)) return(1); avtol = N_VNew_Serial(NEQ); if(check_retval((void *)avtol, "N_VNew_Serial", 0)) return(1); /* Create and initialize y, y', and absolute tolerance vectors. */ yval = N_VGetArrayPointer(yy); yval[0] = ONE; yval[1] = ZERO; yval[2] = ZERO; ypval = N_VGetArrayPointer(yp); ypval[0] = RCONST(-0.04); ypval[1] = RCONST(0.04); ypval[2] = ZERO; rtol = RCONST(1.0e-4); atval = N_VGetArrayPointer(avtol); atval[0] = RCONST(1.0e-8); atval[1] = RCONST(1.0e-6); atval[2] = RCONST(1.0e-6); /* Integration limits */ t0 = ZERO; tout1 = RCONST(0.4); PrintHeader(rtol, avtol, yy); /* Call IDACreate and IDAInit to initialize IDA memory */ mem = IDACreate(); if(check_retval((void *)mem, "IDACreate", 0)) return(1); retval = IDAInit(mem, resrob, t0, yy, yp); if(check_retval(&retval, "IDAInit", 1)) return(1); /* Call IDASVtolerances to set tolerances */ retval = IDASVtolerances(mem, rtol, avtol); if(check_retval(&retval, "IDASVtolerances", 1)) return(1); /* Free avtol */ N_VDestroy(avtol); /* Call IDARootInit to specify the root function grob with 2 components */ retval = IDARootInit(mem, 2, grob); if (check_retval(&retval, "IDARootInit", 1)) return(1); /* Create sparse SUNMatrix for use in linear solves */ nnz = NEQ * NEQ; A = SUNSparseMatrix(NEQ, NEQ, nnz, CSC_MAT); if(check_retval((void *)A, "SUNSparseMatrix", 0)) return(1); /* Create SuperLUMT SUNLinearSolver object (one thread) */ LS = SUNLinSol_SuperLUMT(yy, A, 1); if(check_retval((void *)LS, "SUNLinSol_SuperLUMT", 0)) return(1); /* Attach the matrix and linear solver */ retval = IDASetLinearSolver(mem, LS, A); if(check_retval(&retval, "IDASetLinearSolver", 1)) return(1); /* Set the user-supplied Jacobian routine */ retval = IDASetJacFn(mem, jacrob); if(check_retval(&retval, "IDASetJacFn", 1)) return(1); /* In loop, call IDASolve, print results, and test for error. Break out of loop when NOUT preset output times have been reached. */ iout = 0; tout = tout1; while(1) { retval = IDASolve(mem, tout, &tret, yy, yp, IDA_NORMAL); PrintOutput(mem,tret,yy); if(check_retval(&retval, "IDASolve", 1)) return(1); if (retval == IDA_ROOT_RETURN) { retvalr = IDAGetRootInfo(mem, rootsfound); check_retval(&retvalr, "IDAGetRootInfo", 1); PrintRootInfo(rootsfound[0],rootsfound[1]); } if (retval == IDA_SUCCESS) { iout++; tout *= RCONST(10.0); } if (iout == NOUT) break; } PrintFinalStats(mem); /* Free memory */ IDAFree(&mem); SUNLinSolFree(LS); SUNMatDestroy(A); N_VDestroy(yy); N_VDestroy(yp); return(0); }
void Ida::initialize() { _properties = dynamic_cast<ISystemProperties*>(_system); _continuous_system = dynamic_cast<IContinuous*>(_system); _event_system = dynamic_cast<IEvent*>(_system); _mixed_system = dynamic_cast<IMixedSystem*>(_system); _time_system = dynamic_cast<ITime*>(_system); IGlobalSettings* global_settings = dynamic_cast<ISolverSettings*>(_idasettings)->getGlobalSettings(); // Kennzeichnung, dass initialize()() (vor der Integration) aufgerufen wurde _idid = 5000; _tLastEvent = 0.0; _event_n = 0; SolverDefaultImplementation::initialize(); _dimStates = _continuous_system->getDimContinuousStates(); _dimZeroFunc = _event_system->getDimZeroFunc()+_event_system->getDimClock(); _dimAE = _continuous_system->getDimAE(); if(_dimAE>0) _dimSys=_dimAE+ _dimStates; else _dimSys=_dimStates; if (_dimStates <= 0) { _idid = -1; throw std::invalid_argument("Ida::initialize()"); } else { // Allocate state vectors, stages and temporary arrays /*if (_z) delete[] _z; if (_zInit) delete[] _zInit; if (_zWrite) delete[] _zWrite;*/ if (_y) delete[] _y; if (_yInit) delete[] _yInit; if (_yWrite) delete[] _yWrite; if (_ypWrite) delete[] _ypWrite; if (_yp) delete[] _yp; if (_dae_res) delete[] _dae_res; if (_zeroSign) delete[] _zeroSign; if (_absTol) delete[] _absTol; if(_delta) delete [] _delta; if(_deltaInv) delete [] _deltaInv; if(_ysave) delete [] _ysave; _y = new double[_dimSys]; _yp = new double[_dimSys]; _yInit = new double[_dimSys]; _yWrite = new double[_dimSys]; _ypWrite = new double[_dimSys]; _dae_res = new double[_dimSys]; /* _z = new double[_dimSys]; _zInit = new double[_dimSys]; _zWrite = new double[_dimSys]; */ _zeroSign = new int[_dimZeroFunc]; _absTol = new double[_dimSys]; _delta =new double[_dimSys]; _deltaInv =new double[_dimSys]; _ysave =new double[_dimSys]; memset(_y, 0, _dimSys * sizeof(double)); memset(_yp, 0, _dimSys * sizeof(double)); memset(_yInit, 0, _dimSys * sizeof(double)); memset(_ysave, 0, _dimSys * sizeof(double)); std::fill_n(_absTol, _dimSys, 1.0); // Counter initialisieren _outStps = 0; if (_idasettings->getDenseOutput()) { // Ausgabeschrittweite _hOut = global_settings->gethOutput(); } // Allocate memory for the solver _idaMem = IDACreate(); if (check_flag((void*) _idaMem, "IDACreate", 0)) { _idid = -5; throw std::invalid_argument(/*_idid,_tCurrent,*/"Ida::initialize()"); } // // Make Ida ready for integration // // Set initial values for IDA //_continuous_system->evaluateAll(IContinuous::CONTINUOUS); _continuous_system->getContinuousStates(_yInit); memcpy(_y, _yInit, _dimStates * sizeof(double)); if(_dimAE>0) { _mixed_system->getAlgebraicDAEVars(_yInit+_dimStates); memcpy(_y+_dimStates, _yInit+_dimStates, _dimAE * sizeof(double)); _continuous_system->getContinuousStates(_yp); } // Get nominal values _continuous_system->getNominalStates(_absTol); for (int i = 0; i < _dimStates; i++) _absTol[i] = dynamic_cast<ISolverSettings*>(_idasettings)->getATol(); _CV_y0 = N_VMake_Serial(_dimSys, _yInit); _CV_y = N_VMake_Serial(_dimSys, _y); _CV_yp = N_VMake_Serial(_dimSys, _yp); _CV_yWrite = N_VMake_Serial(_dimSys, _yWrite); _CV_ypWrite = N_VMake_Serial(_dimSys, _ypWrite); _CV_absTol = N_VMake_Serial(_dimSys, _absTol); if (check_flag((void*) _CV_y0, "N_VMake_Serial", 0)) { _idid = -5; throw std::invalid_argument("Ida::initialize()"); } //is already initialized: calcFunction(_tCurrent, NV_DATA_S(_CV_y0), NV_DATA_S(_CV_yp),NV_DATA_S(_CV_yp)); // Initialize Ida (Initial values are required) _idid = IDAInit(_idaMem, rhsFunctionCB, _tCurrent, _CV_y0, _CV_yp); if (_idid < 0) { _idid = -5; throw std::invalid_argument("Ida::initialize()"); } _idid = IDASetErrHandlerFn(_idaMem, errOutputIDA, _data); if (_idid < 0) throw std::invalid_argument("IDA::initialize()"); // Set Tolerances _idid = IDASVtolerances(_idaMem, dynamic_cast<ISolverSettings*>(_idasettings)->getRTol(), _CV_absTol); // RTOL and ATOL if (_idid < 0) throw std::invalid_argument("IDA::initialize()"); // Set the pointer to user-defined data _idid = IDASetUserData(_idaMem, _data); if (_idid < 0) throw std::invalid_argument("IDA::initialize()"); _idid = IDASetInitStep(_idaMem, 1e-6); // INITIAL STEPSIZE if (_idid < 0) throw std::invalid_argument("Ida::initialize()"); _idid = IDASetMaxStep(_idaMem, global_settings->getEndTime() / 10.0); // MAXIMUM STEPSIZE if (_idid < 0) throw std::invalid_argument("IDA::initialize()"); _idid = IDASetMaxNonlinIters(_idaMem, 5); // Max number of iterations if (_idid < 0) throw std::invalid_argument("IDA::initialize()"); _idid = IDASetMaxErrTestFails(_idaMem, 100); if (_idid < 0) throw std::invalid_argument("IDA::initialize()"); _idid = IDASetMaxNumSteps(_idaMem, 1e3); // Max Number of steps if (_idid < 0) throw std::invalid_argument(/*_idid,_tCurrent,*/"IDA::initialize()"); // Initialize linear solver _idid = IDADense(_idaMem, _dimSys); if (_idid < 0) throw std::invalid_argument("IDA::initialize()"); if(_dimAE>0) { _idid = IDASetSuppressAlg(_idaMem, TRUE); double* tmp = new double[_dimSys]; std::fill_n(tmp, _dimStates, 1.0); std::fill_n(tmp+_dimStates, _dimAE, 0.0); _idid = IDASetId(_idaMem, N_VMake_Serial(_dimSys,tmp)); delete [] tmp; if (_idid < 0) throw std::invalid_argument("IDA::initialize()"); } // Use own jacobian matrix //_idid = CVDlsSetDenseJacFn(_idaMem, &jacobianFunctionCB); //if (_idid < 0) // throw std::invalid_argument("IDA::initialize()"); if (_dimZeroFunc) { _idid = IDARootInit(_idaMem, _dimZeroFunc, &zeroFunctionCB); memset(_zeroSign, 0, _dimZeroFunc * sizeof(int)); _idid = IDASetRootDirection(_idaMem, _zeroSign); if (_idid < 0) throw std::invalid_argument(/*_idid,_tCurrent,*/"IDA::initialize()"); memset(_zeroSign, -1, _dimZeroFunc * sizeof(int)); memset(_zeroVal, -1, _dimZeroFunc * sizeof(int)); } _ida_initialized = true; // // IDA is ready for integration // // BOOST_LOG_SEV(ida_lg::get(), ida_info) << "IDA initialized"; } }
/* creates CVODES structures and fills cvodeSolver return 1 => success return 0 => failure */ int IntegratorInstance_createIDASolverStructures(integratorInstance_t *engine) { int i, flag, neq, nalg; realtype *ydata, *abstoldata, *dydata; odeModel_t *om = engine->om; cvodeData_t *data = engine->data; cvodeSolver_t *solver = engine->solver; cvodeSettings_t *opt = engine->opt; neq = engine->om->neq; /* number of ODEs */ nalg = engine->om->nalg; /* number of algebraic constraints */ /* construct jacobian, if wanted and not yet existing */ if ( opt->UseJacobian && om->jacob == NULL ) /* reset UseJacobian option, depending on success */ engine->UseJacobian = ODEModel_constructJacobian(om); else if ( !opt->UseJacobian ) { /* free jacobian from former runs (not necessary, frees also unsuccessful jacobians from former runs ) */ ODEModel_freeJacobian(om); SolverError_error(WARNING_ERROR_TYPE, SOLVER_ERROR_MODEL_NOT_SIMPLIFIED, "Jacobian matrix construction skipped."); engine->UseJacobian = om->jacobian; } /* construct algebraic `Jacobian' (or do that in constructJacobian */ /* CVODESolverStructures from former runs must be freed */ if ( engine->run > 1 ) IntegratorInstance_freeIDASolverStructures(engine); /* * Allocate y, abstol vectors */ solver->y = N_VNew_Serial(neq + nalg); CVODE_HANDLE_ERROR((void *)solver->y, "N_VNew_Serial for vector y", 0); solver->dy = N_VNew_Serial(neq + nalg); CVODE_HANDLE_ERROR((void *)solver->dy, "N_VNew_Serial for vector dy", 0); solver->abstol = N_VNew_Serial(neq + nalg); CVODE_HANDLE_ERROR((void *)solver->abstol, "N_VNew_Serial for vector abstol", 0); /* * Initialize y, abstol vectors */ ydata = NV_DATA_S(solver->y); abstoldata = NV_DATA_S(solver->abstol); dydata = NV_DATA_S(solver->dy); for ( i=0; i<neq; i++ ) { /* Set initial value vector components of y and y' */ ydata[i] = data->value[i]; /* Set absolute tolerance vector components, currently the same absolute error is used for all y */ abstoldata[i] = opt->Error; dydata[i] = evaluateAST(om->ode[i], data); } /* set initial value vector components for algebraic rule variables */ /* scalar relative tolerance: the same for all y */ solver->reltol = opt->RError; /* * Call IDACreate to create the solver memory: * */ solver->cvode_mem = IDACreate(); CVODE_HANDLE_ERROR((void *)(solver->cvode_mem), "IDACreate", 0); /* * Call IDAInit to initialize the integrator memory: * * cvode_mem pointer to the CVode memory block returned by CVodeCreate * fRes user's right hand side function * t0 initial value of time * y the dependent variable vector * dy the ODE value vector */ flag = IDAInit(solver->cvode_mem, fRes, solver->t0, solver->y, solver->dy); CVODE_HANDLE_ERROR(&flag, "IDAInit", 1); /* * specify scalar relative and vector absolute tolerances * reltol the scalar relative tolerance * abstol pointer to the absolute tolerance vector */ flag = IDASVtolerances(solver->cvode_mem, solver->reltol, solver->abstol); CVODE_HANDLE_ERROR(&flag, "IDASVtolerances", 1); /* * Link the main integrator with data for right-hand side function */ flag = IDASetUserData(solver->cvode_mem, engine->data); CVODE_HANDLE_ERROR(&flag, "IDASetUserData", 1); /* * Link the main integrator with the IDADENSE linear solver */ flag = IDADense(solver->cvode_mem, neq); CVODE_HANDLE_ERROR(&flag, "IDADense", 1); /* * Set the routine used by the IDADense linear solver * to approximate the Jacobian matrix to ... */ if ( opt->UseJacobian == 1 ) { /* ... user-supplied routine JacRes : put JacRes instead of NULL when working */ flag = IDADlsSetDenseJacFn(solver->cvode_mem, JacRes); CVODE_HANDLE_ERROR(&flag, "IDADlsSetDenseJacFn", 1); } return 1; /* OK */ }
CAMLprim value sundials_ml_ida_sv_tolerances(value ida_solver, value reltol, value abstol) { CAMLparam3(ida_solver, reltol, abstol); BA_STACK_NVECTOR(abstol, nv_abstol); const int ret = IDASVtolerances(IDA_MEM(ida_solver), Double_val(reltol), &nv_abstol); CAMLreturn(Val_int(ret)); }
void SundialsIda::initialize() { sundialsMem = IDACreate(); if (check_flag((void *)sundialsMem, "IDACreate", 0)) { throw DebugException("SundialsIda::initialize: error in IDACreate"); } IDASetUserData(sundialsMem, theDAE); int flag; if (calcIC) { // Pick an appropriate initial condition for ydot and algebraic components of y flag = IDASetId(sundialsMem, componentId.forSundials()); } flag = IDAInit(sundialsMem, f, t0, y.forSundials(), ydot.forSundials()); if (check_flag(&flag, "IDAMalloc", 1)) { throw DebugException("SundialsIda::initialize: error in IDAInit"); } IDASVtolerances(sundialsMem, reltol, abstol.forSundials()); if (findRoots) { rootsFound.resize(nRoots); // Call IDARootInit to specify the root function g with nRoots components flag = IDARootInit(sundialsMem, nRoots, g); if (check_flag(&flag, "IDARootInit", 1)) { throw DebugException("SundialsIda::initialize: error in IDARootInit"); } } // Call IDASpbcg to specify the IDASpbcg dense linear solver flag = IDASpbcg(sundialsMem, 0); if (check_flag(&flag, "IDASpbcg", 1)) { throw DebugException("SundialsIda::initialize: error in IDASpbcg"); } if (imposeConstraints) { flag = IDASetConstraints(sundialsMem, constraints.forSundials()); if (check_flag(&flag, "IDASetConstraints", 1)) { throw DebugException("SundialsIda::initialize: error in IDASetConstraints"); } } // this seems to work better using the default J-v function rather than specifying our own... //flag = IDASpilsSetJacTimesVecFn(sundialsMem, JvProd, theDAE); //if (check_flag(&flag, "IDASpilsSetJacTimesVecFn", 1)) { // throw myException("SundialsIda::initialize: error in IDASpilsSetJacTimesVecFn"); //} flag = IDASpilsSetPreconditioner(sundialsMem, preconditionerSetup, preconditionerSolve); if (check_flag(&flag, "IDASpilsSetPreconditioner", 1)) { throw DebugException("SundialsIda::initialize: error in IDASpilsSetPreconditioner"); } if (calcIC) { flag = IDACalcIC(sundialsMem, IDA_YA_YDP_INIT, t0+1e-4); if (check_flag(&flag, "IDACalcIC", 1)) { logFile.write("IDACalcIC Error"); throw DebugException("SundialsIda::initialize: error in IDACalcIC"); } flag = IDAGetConsistentIC(sundialsMem, y0.forSundials(), ydot0.forSundials()); if (check_flag(&flag, "IDAGetConsistentIC", 1)) { throw DebugException("SundialsIda::initialize: error in IDAGetConsistentIC"); } } }