9 #include "sundials/sundials_types.h" 10 #include "sundials/sundials_math.h" 12 #include "ida/ida_dense.h" 13 #include "ida/ida_spgmr.h" 14 #include "ida/ida_band.h" 15 #include "nvector/nvector_serial.h" 19 #if SUNDIALS_VERSION < 25 20 typedef int sd_size_t;
22 typedef long int sd_size_t;
65 static int ida_resid(realtype t, N_Vector y, N_Vector ydot, N_Vector r,
void* f_data)
72 int flag = f->
evalResidNJ(t, delta_t, NV_DATA_S(y), NV_DATA_S(ydot),
97 static int ida_jacobian(sd_size_t nrows, realtype t, realtype c_j, N_Vector y, N_Vector ydot, N_Vector r,
98 DlsMat Jac,
void* f_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
105 Jac->cols, NV_DATA_S(r));
139 m_maxErrTestFails(-1),
141 m_maxNonlinConvFails(-1),
148 IDA_Solver::~IDA_Solver()
154 N_VDestroy_Serial(
m_y);
157 N_VDestroy_Serial(
m_ydot);
160 N_VDestroy_Serial(m_abstol);
163 N_VDestroy_Serial(m_constraints);
169 return NV_Ith_S(
m_y,k);
172 const doublereal* IDA_Solver::solutionVector()
const 174 return NV_DATA_S(
m_y);
179 return NV_Ith_S(
m_ydot,k);
182 const doublereal* IDA_Solver::derivativeVector()
const 191 m_abstol = N_VNew_Serial(
m_neq);
193 for (
int i = 0; i <
m_neq; i++) {
194 NV_Ith_S(m_abstol, i) = abstol[i];
198 int flag = IDASVtolerances(
m_ida_mem, m_reltol, m_abstol);
199 if (flag != IDA_SUCCESS) {
201 "Memory allocation failed.");
212 int flag = IDASStolerances(
m_ida_mem, m_reltol, m_abstols);
213 if (flag != IDA_SUCCESS) {
215 "Memory allocation failed.");
220 void IDA_Solver::setLinearSolverType(
int solverType)
227 setLinearSolverType(0);
237 void IDA_Solver::setMaxOrder(
int n)
269 if (flag != IDA_SUCCESS) {
271 "IDADlsSetDenseJacFn failed.");
276 void IDA_Solver::setMaxErrTestFailures(
int maxErrTestFails)
291 void IDA_Solver::inclAlgebraicInErrorTest(
bool yesno)
307 N_VDestroy_Serial(
m_y);
310 N_VDestroy_Serial(
m_ydot);
313 N_VDestroy_Serial(m_id);
316 N_VDestroy_Serial(m_constraints);
321 m_constraints = N_VNew_Serial(
m_neq);
323 for (
int i=0; i<
m_neq; i++) {
324 NV_Ith_S(
m_y, i) = 0.0;
325 NV_Ith_S(
m_ydot, i) = 0.0;
326 NV_Ith_S(m_constraints, i) = 0.0;
340 if (m_itol == IDA_SV) {
342 if (flag != IDA_SUCCESS) {
343 if (flag == IDA_MEM_FAIL) {
345 "Memory allocation failed.");
346 }
else if (flag == IDA_ILL_INPUT) {
348 "Illegal value for IDAInit input argument.");
350 throw CanteraError(
"IDA_Solver::init",
"IDAInit failed.");
353 flag = IDASVtolerances(
m_ida_mem, m_reltol, m_abstol);
354 if (flag != IDA_SUCCESS) {
355 throw CanteraError(
"IDA_Solver::init",
"Memory allocation failed.");
359 if (flag != IDA_SUCCESS) {
360 if (flag == IDA_MEM_FAIL) {
362 "Memory allocation failed.");
363 }
else if (flag == IDA_ILL_INPUT) {
365 "Illegal value for IDAInit input argument.");
367 throw CanteraError(
"IDA_Solver::init",
"IDAInit failed.");
370 flag = IDASStolerances(
m_ida_mem, m_reltol, m_abstols);
371 if (flag != IDA_SUCCESS) {
372 throw CanteraError(
"IDA_Solver::init",
"Memory allocation failed.");
377 if (m_type == 1 || m_type == 0) {
381 throw CanteraError(
"IDA_Solver::init",
"IDADense failed");
383 }
else if (m_type == 2) {
385 long int nu = m_mupper;
386 long int nl = m_mlower;
390 "unsupported linear solver type");
395 if (flag != IDA_SUCCESS) {
397 "IDADlsSetDenseJacFn failed.");
403 flag = IDASetUserData(
m_ida_mem, m_fdata.get());
404 if (flag != IDA_SUCCESS) {
405 throw CanteraError(
"IDA_Solver::init",
"IDASetUserData failed.");
411 if (flag != IDA_SUCCESS) {
412 throw CanteraError(
"IDA_Solver::init",
"IDASetMaxOrd failed.");
417 if (flag != IDA_SUCCESS) {
418 throw CanteraError(
"IDA_Solver::init",
"IDASetMaxNumSteps failed.");
423 if (flag != IDA_SUCCESS) {
424 throw CanteraError(
"IDA_Solver::init",
"IDASetInitStep failed.");
429 if (flag != IDA_SUCCESS) {
430 throw CanteraError(
"IDA_Solver::init",
"IDASetStopTime failed.");
435 if (flag != IDA_SUCCESS) {
437 "IDASetMaxErrTestFails failed.");
442 if (flag != IDA_SUCCESS) {
444 "IDASetmaxNonlinIters failed.");
449 if (flag != IDA_SUCCESS) {
451 "IDASetMaxConvFails failed.");
456 if (flag != IDA_SUCCESS) {
457 throw CanteraError(
"IDA_Solver::init",
"IDASetSuppressAlg failed.");
464 doublereal tout1 = tout;
473 int flag = IDACalcIC(
m_ida_mem, IDA_Y_INIT, tout1);
474 if (flag != IDA_SUCCESS) {
475 throw CanteraError(
"IDA_Solver::correctInitial_Y_given_Yp",
476 "IDACalcIC failed: error = {}", flag);
480 if (flag != IDA_SUCCESS) {
481 throw CanteraError(
"IDA_Solver::correctInitial_Y_given_Yp",
482 "IDAGetSolution failed: error = {}", flag);
484 for (
int i = 0; i <
m_neq; i++) {
485 y[i] = NV_Ith_S(
m_y, i);
486 yp[i] = NV_Ith_S(
m_ydot, i);
492 int icopt = IDA_YA_YDP_INIT;
493 doublereal tout1 = tout;
502 int flag = IDACalcIC(
m_ida_mem, icopt, tout1);
503 if (flag != IDA_SUCCESS) {
504 throw CanteraError(
"IDA_Solver::correctInitial_YaYp_given_Yd",
505 "IDACalcIC failed: error = {}", flag);
509 if (flag != IDA_SUCCESS) {
510 throw CanteraError(
"IDA_Solver::correctInitial_YaYp_given_Yd",
511 "IDAGetSolution failed: error = {}", flag);
513 for (
int i = 0; i <
m_neq; i++) {
514 y[i] = NV_Ith_S(
m_y, i);
515 yp[i] = NV_Ith_S(
m_ydot, i);
521 double tretn = tout - 1000;
524 if (flag != IDA_SUCCESS) {
525 throw CanteraError(
"IDA_Solver::solve",
"IDA error encountered.");
527 while (tretn < tout) {
529 throw CanteraError(
"IDA_Solver::solve",
"tout <= tcurrent");
535 throw CanteraError(
"IDA_Solver::solve",
"IDA error encountered.");
536 }
else if (flag == IDA_TSTOP_RETURN) {
538 }
else if (flag == IDA_ROOT_RETURN) {
540 }
else if (flag == IDA_WARNING) {
541 throw CanteraError(
"IDA_Solver::solve",
"IDA Warning encountered.");
547 if (flag != IDA_SUCCESS && flag != IDA_TSTOP_RETURN) {
548 throw CanteraError(
"IDA_Solver::solve",
"IDA error encountered.");
558 throw CanteraError(
"IDA_Solver::step",
"tout <= tcurrent");
564 throw CanteraError(
"IDA_Solver::step",
"IDA error encountered.");
565 }
else if (flag == IDA_TSTOP_RETURN) {
567 }
else if (flag == IDA_ROOT_RETURN) {
569 }
else if (flag == IDA_WARNING) {
570 throw CanteraError(
"IDA_Solver::step",
"IDA Warning encountered.");
579 long int lenrw, leniw;
581 case REAL_WORKSPACE_SIZE:
582 flag = IDAGetWorkSpace(
m_ida_mem, &lenrw, &leniw);
583 return doublereal(lenrw);
virtual void setStopTime(doublereal tstop)
Set the stop time.
virtual int evalJacobianDP(const doublereal t, const doublereal delta_t, doublereal cj, const doublereal *const y, const doublereal *const ydot, doublereal *const *jacobianColPts, doublereal *const resid)
Calculate an analytical Jacobian and the residual at the current time and values. ...
A simple class to hold an array of parameter values and a pointer to an instance of a subclass of Res...
integer m_neq
Number of total equations in the system.
Wrapper for Sundials IDA solver.
int m_maxNonlinConvFails
Maximum number of nonlinear convergence failures.
int nparams() const
Return the number of parameters in the calculation.
virtual void setBandedLinearSolver(int m_upper, int m_lower)
Set up the problem to use a band solver.
doublereal m_told
Value of the previous time.
int m_maxsteps
Maximum number of time steps allowed.
virtual double getCurrentStepFromIDA()
Get the current step size from IDA via a call.
virtual void setInitialStepSize(doublereal h0)
Set the initial step size.
virtual void setDenseLinearSolver()
Set up the problem to use a dense linear direct solver.
virtual int evalResidNJ(const doublereal t, const doublereal delta_t, const doublereal *const y, const doublereal *const ydot, doublereal *const resid, const ResidEval_Type_Enum evalType=Base_ResidEval, const int id_x=-1, const doublereal delta_x=0.0)
Evaluate the residual function.
int m_maxErrTestFails
maximum number of error test failures
virtual void correctInitial_YaYp_given_Yd(doublereal *y, doublereal *yp, doublereal tout)
Calculate consistent value of the algebraic constraints and derivatives at the start of the problem...
doublereal m_tstop
maximum time
doublereal m_tcurrent
Value of the current time.
virtual int getInitialConditions(const doublereal t0, doublereal *const y, doublereal *const ydot)
Fill in the initial conditions.
virtual void setMaxNonlinConvFailures(int n)
Set the maximum number of nonlinear solver convergence failures.
doublereal m_told_old
Value of the previous, previous time.
static int ida_resid(realtype t, N_Vector y, N_Vector ydot, N_Vector r, void *f_data)
Function called by IDA to evaluate the residual, given y and ydot.
Wrappers for the function evaluators for Nonlinear solvers and Time steppers.
void * m_ida_mem
Pointer to the IDA memory for the problem.
virtual void setMaxNumSteps(int n)
Set the maximum number of time steps.
N_Vector m_y
Current value of the solution vector.
doublereal m_h0
Value of the initial time step.
virtual int solve(doublereal tout)
Step the system to a final value of the time.
virtual void correctInitial_Y_given_Yp(doublereal *y, doublereal *yp, doublereal tout)
Calculate consistent value of the starting solution given the starting solution derivatives.
doublereal m_deltat
Value of deltaT for the current step.
virtual doublereal solution(int k) const
the current value of solution component k.
Base class for exceptions thrown by Cantera classes.
virtual doublereal derivative(int k) const
the current value of the derivative of solution component k.
virtual void setMaxNonlinIterations(int n)
Set the maximum number of nonlinear iterations on a timestep.
virtual void setJacobianType(int formJac)
Set the form of the Jacobian.
virtual doublereal getOutputParameter(int flag) const
Get the value of a solver-specific output parameter.
virtual void init(doublereal t0)
initialize.
Contains declarations for string manipulation functions within Cantera.
int m_maxNonlinIters
Maximum number of nonlinear solver iterations at one solution.
doublereal m_t0
Initial value of the time.
N_Vector m_ydot
Current value of the derivative of the solution vector.
Header file for class IDA_Solver.
virtual doublereal step(doublereal tout)
Take one internal step.
Namespace for the Cantera kernel.
int m_maxord
maximum time step order of the method
virtual void setTolerances(doublereal reltol, doublereal *abstol)
Set error tolerances.
static int ida_jacobian(sd_size_t nrows, realtype t, realtype c_j, N_Vector y, N_Vector ydot, N_Vector r, DlsMat Jac, void *f_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
Function called by by IDA to evaluate the Jacobian, given y and ydot.
int m_formJac
Form of the Jacobian.
int m_setSuppressAlg
If true, the algebraic variables don't contribute to error tolerances.